如何让.Net线程支持超时后并自动销毁!

现实生活中,我们往往会遇到,要执行一个线程的方法,假如这个方法特别耗时,我怎么才能在指定的线程超时时间内,取消执行,并把线程销毁!以下是本人总结的常见几种方式!特此做下笔记!

1.使用CancellationTokenSource之基于Task实现方式

CancellationTokenSource source = new CancellationTokenSource();
        source.CancelAfter(TimeSpan.FromMilliseconds(2000));
        Task task=Task.Factory.StartNew(() =>
        {
            while (true)
            {
                try
                {
                    source.Token.ThrowIfCancellationRequested();
                    Console.WriteLine("子方法执行中...");


                    Thread.Sleep(1000);
                    Console.WriteLine("子方法执行完毕...");
                }
                catch (OperationCanceledException ex)
                {
                    Console.WriteLine("已捕获取消异常:" + ex.Message);
                    break;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("异常:" + ex.Message);
                    break;
                }

            }
            Console.WriteLine("线程已终止");

        }, source.Token);

2.使用CancellationTokenSource之基于Thread实现方式

 CancellationTokenSource source = new CancellationTokenSource();
        Thread thread = new Thread(new ThreadStart(() =>
        {

            while (true)
            {
                Console.WriteLine("现在时间:"+DateTime.Now);
            }
        }));
        thread.IsBackground = true;
        thread.Start();

        source.Token.Register(() =>
        {
            Console.WriteLine("超时时间已到,开始终止线程");
            thread.Abort();
            Console.WriteLine("超时时间已到,终止线程完成");
        });
        source.CancelAfter(2000);

3.基于Thread.Join()实现

 Thread thread =new Thread(new ThreadStart(() =>
        {
            while (true)
            {
                Console.WriteLine("现在时间:"+DateTime.Now);
            }
        }));
        thread.Start();
        thread.Join(2000);
        Console.WriteLine("join超时时间已到,开始终止线程");
        thread.Abort();
        Console.WriteLine("join超时时间已到,终止线程完成");

4.基于System.Timers.Timer的实现方式

DateTime dtNow = DateTime.Now;
        Thread thread = new Thread(new ThreadStart(() =>
        {
            while (true)
            {
                Console.WriteLine("现在时间:" + DateTime.Now);
            }

        }));
        thread.IsBackground = true;
        thread.Start();
        System.Timers.Timer timer = new System.Timers.Timer();
        timer.Interval = 1000;
        timer.Elapsed += (sender,e) =>
        {
            double db=DateTime.Now.Subtract(dtNow).TotalSeconds;
            if (db > 2)//大于2秒说明已经超时
            {
                Console.WriteLine("任务已执行超过了:" + db + "秒");
                Console.WriteLine("超时时间已到,开始终止线程");
                thread.Abort();
                Console.WriteLine("超时时间已到,终止线程完成");
                timer.Stop();
            }
        };
        timer.Start();

5.基于信号量和CancellationTokenSource的实现方式

AutoResetEvent autoReset = new AutoResetEvent(false);
        CancellationTokenSource source = new CancellationTokenSource();

        Task.Factory.StartNew(() =>
        {
            try
            {
                while (true)
                {
                    source.Token.ThrowIfCancellationRequested();
                    Console.WriteLine("子线程:Work starting.");

                    // Simulate time spent working.
                    Thread.Sleep(5000);//new Random().Next(500, 2000)
                    autoReset.Set();
                    // Signal that work is finished.
                    Console.WriteLine("子线程:Work ending.");

                }
            }
            catch (Exception e)
            {
                autoReset.Set();
                Console.WriteLine("子线程收到异常:"+e.Message+",线程退出!");
               // throw;
            }



        }, source.Token);
        Console.WriteLine("主线程只等待1秒");
        autoReset.WaitOne(1000);//等待超过1秒,则需要取消该线程
        Console.WriteLine("主线程等待超时,开始继续执行,同时调用Source.Cancel()");
        source.Cancel();
posted @ 2017-06-16 13:57  无处安放的青春  阅读(561)  评论(2编辑  收藏  举报