using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
    /// 
    /// 超时类,可设置执行方法超时时间
    /// 目前没有添加取消方法,如有需要,可添加取消功能
    /// 
    public class OutTimeClass
    {
        #region delegate
        /// 
        /// 无参数,无反回值方法
        /// 
        public delegate void NotParamDelegate();
        /// 
        /// 有参数,无反回值方法
        /// 
        /// 
        public delegate void SomeParamsDelegate(object Params);
        /// 
        /// 无参数,带返回值方法
        /// 
        /// 
        public delegate object NotParamReturnDelegate();
        /// 
        /// 有参数,有反回值方法
        /// 
        /// 
        /// 
        public delegate object SomeParamsReturnDelegate(object Params);
        #endregion
        #region 超时方法
        /// 
        /// 无参数,无反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间(毫秒)
        public static void OutTimeNotParam(NotParamDelegate Method, int OutTimeMilliseconds)
        {
            OutTimeNotParam(Method, TimeSpan.FromMilliseconds(OutTimeMilliseconds));
        }
        /// 
        /// 无参数,无反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间
        public static void OutTimeNotParam(NotParamDelegate Method, TimeSpan OutTime)
        {
            OutTimeNotParam(Method, OutTime, null);
        }
        /// 
        /// 无参数,无反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间
        /// 取消信号
        public static void OutTimeNotParam(NotParamDelegate Method, TimeSpan OutTime, WaitHandle cancelEvent)
        {
            AutoResetEvent are = new AutoResetEvent(false);
            Thread t = new Thread(delegate () { Method(); are.Set(); });
            t.IsBackground = true;
            t.Start();
            Wait(t, OutTime, are, cancelEvent);
        }
        /// 
        /// 有参数,无反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间(毫秒)
        /// 参数
        public static void OutTimeSomeParem(SomeParamsDelegate Method, int OutTimeMilliseconds, object Param)
        {
            OutTimeSomeParem(Method, TimeSpan.FromMilliseconds(OutTimeMilliseconds), Param);
        }
        /// 
        /// 有参数,无反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间
        /// 参数
        public static void OutTimeSomeParem(SomeParamsDelegate Method, TimeSpan OutTime, object Param)
        {
            OutTimeSomeParem(Method, OutTime, Param, null);
        }
        /// 
        /// 有参数,无反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间
        /// 取消信号
        /// 参数
        public static void OutTimeSomeParem(SomeParamsDelegate Method, TimeSpan OutTime, object Param, WaitHandle cancelEvent)
        {
            AutoResetEvent are = new AutoResetEvent(false);
            Thread t = new Thread(delegate () { Method(Param); are.Set(); });
            t.Start();
            Wait(t, OutTime, are, cancelEvent);
        }
        /// 
        /// 没参数,有反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间(毫秒)
        /// 反回object类型对象
        public static object OutTimeNotParamReturn(NotParamReturnDelegate Method, int OutTimeMilliseconds)
        {
            return OutTimeNotParamReturn(Method, TimeSpan.FromMilliseconds(OutTimeMilliseconds));
        }
        /// 
        /// 没参数,有反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间
        /// 反回object类型对象
        public static object OutTimeNotParamReturn(NotParamReturnDelegate Method, TimeSpan OutTime)
        {
            return OutTimeNotParamReturn(Method, OutTime, null);
        }
        /// 
        /// 没参数,有反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间
        /// 取消信号
        /// 反回object类型对象
        public static object OutTimeNotParamReturn(NotParamReturnDelegate Method, TimeSpan OutTime, WaitHandle cancelEvent)
        {
            object obj = null;
            AutoResetEvent are = new AutoResetEvent(false);
            Thread t = new Thread(delegate () { obj = Method(); are.Set(); });
            t.Start();
            Wait(t, OutTime, are, cancelEvent);
            return obj;
        }
        /// 
        /// 有参数,有反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间
        /// 执行参数
        /// 反回一个object类型方法
        public static object OutTimeSomeParemReturn(SomeParamsReturnDelegate Method, int OutTimeMilliseconds, object Param)
        {
            return OutTimeSomeParemReturn(Method, TimeSpan.FromMilliseconds(OutTimeMilliseconds), Param);
        }
        /// 
        /// 有参数,有反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间
        /// 执行参数
        /// 反回一个object类型方法
        public static object OutTimeSomeParemReturn(SomeParamsReturnDelegate Method, TimeSpan OutTime, object Param)
        {
            return OutTimeSomeParemReturn(Method, OutTime, Param, null);
        }
        /// 
        /// 有参数,有反回值超时方法
        /// 
        /// 执行方法
        /// 超时时间
        /// 执行参数
        /// 取消信号
        /// 反回一个object类型方法
        public static object OutTimeSomeParemReturn(SomeParamsReturnDelegate Method, TimeSpan OutTime, object Param, WaitHandle cancelEvent)
        {
            object obj = null;
            AutoResetEvent are = new AutoResetEvent(false);
            Thread t = new Thread(delegate () { obj = Method(Param); are.Set(); });
            t.Start();
            Wait(t, OutTime, are, cancelEvent);
            return obj;
        }
        /// 
        /// 等待方法执行完成,或超时
        /// 
        /// 
        /// 
        /// 
        private static void Wait(Thread t, TimeSpan OutTime, WaitHandle are, WaitHandle cancelEvent)
        {
            WaitHandle[] ares;
            if (cancelEvent == null)
                ares = new WaitHandle[] { are };
            else
                ares = new WaitHandle[] { are, cancelEvent };
            int index = WaitHandle.WaitAny(ares, OutTime);
            if ((index != 0) && t.IsAlive)//如果不是执行完成的信号,并且,线程还在执行,那么,结束这个线程
            {
                //t.Abort();//不支持
                t.Interrupt();
                t = null;
            }
        }
        #endregion
    }
    public class ThreadHelper
    {
        static CancellationTokenSource _cancelSource01 = new CancellationTokenSource();
        static CancellationTokenSource _cancelSource02 = new CancellationTokenSource();
        public static void TaskThread(Action methodName, int timeout = 0)
        {
            var task = Task.Factory.StartNew(() =>
            {
                methodName();
            }, _cancelSource01.Token);
            if (timeout > 0)
            {
                task.Wait(timeout);
                _cancelSource01.Cancel();
            }
        }
        public static void TaskThread(Action