• 让线程支持超时


    目录

    背景如何让线程支持超时?使用 CancellationTokenSource使用 Join基于 Task 的实现如何让线程在执行结束后销毁?备注

    背景返回目录

    本文是为了回复博客园一个兄弟的问题,主要回答两个问题:

    1. 如何让线程支持超时?
    2. 如何让线程在执行结束后销毁?

    MS 现在不推荐使用低级别的 Thread 编程,而推荐使用 Task,另外我多数情况都是做企业应用,很少需要多线程编程的场景,本文中的知识都是从 《clr via c#》学习而来。

    如何让线程支持超时?返回目录

    使用 CancellationTokenSource返回目录

    代码

    复制代码
     1         private static void TimeoutTest1()
     2         {
     3             var cts = new CancellationTokenSource();
     4 
     5             var thread = new Thread(() =>
     6             {
     7                 Console.WriteLine(String.Format("线程{0}执行中", Thread.CurrentThread.ManagedThreadId));
     8                 Thread.Sleep(10000);
     9                 Console.WriteLine(String.Format("线程{0}执行中", Thread.CurrentThread.ManagedThreadId));
    10             });
    11 
    12             cts.Token.Register(() =>
    13             {
    14                 thread.Abort();
    15             });
    16             cts.CancelAfter(1000);
    17 
    18             thread.Start();
    19             thread.Join();
    20 
    21             Console.WriteLine(String.Format("线程{0}的状态:{1}", thread.ManagedThreadId, thread.ThreadState));
    22         }
    复制代码

    输出

    备注

    这里采用了 Abort 终止了线程,CancellationTokenSource 也支持其它模式,可以去官方看看文档。

    使用 Join返回目录

    代码

    复制代码
     1         private static void TimeoutTest2()
     2         {
     3             var thread = new Thread(() =>
     4             {
     5                 Console.WriteLine(String.Format("线程{0}执行中", Thread.CurrentThread.ManagedThreadId));
     6                 Thread.Sleep(10000);
     7                 Console.WriteLine(String.Format("线程{0}执行中", Thread.CurrentThread.ManagedThreadId));
     8             });
     9 
    10             thread.Start();
    11             thread.Join(1000);
    12             thread.Abort();
    13 
    14             Console.WriteLine(String.Format("线程{0}的状态:{1}", thread.ManagedThreadId, thread.ThreadState));
    15         }
    复制代码

    输出

    基于 Task 的实现返回目录

    代码

    复制代码
     1         private static void TimeoutTest3()
     2         {
     3             var cts = new CancellationTokenSource();
     4             var task = new Task(() =>
     5             {
     6                 while (true)
     7                 {
     8                     cts.Token.ThrowIfCancellationRequested();
     9 
    10                     Console.WriteLine("xxxxxx");
    11                     Thread.Sleep(1000);
    12                 }
    13             }, cts.Token);
    14 
    15             task.Start();
    16 
    17             cts.CancelAfter(5000);
    18 
    19             Console.ReadLine();
    20         }
    复制代码

    输出

    如何让线程在执行结束后销毁?返回目录

    线程执行完、遇到未处理异常和被终止后就自动不可用了,如果是垃圾,自然会被 GC 给回收,有一点需要说明的是:线程的未处理异常会导致应用程序的终止,一个线程的异常不会自动冒泡到其它线程。

    备注返回目录

    我学习多线程知识感觉到的一个好处就是:让我对数据库并发有了更深刻的认识了,找个机会写写线程的乐观锁和数据库的乐观锁的比较,思路基本一样。

  • 相关阅读:
    jsp第六周作业
    jsp第四次作业
    JSP第二次作业 2021 0310
    软件测试作业 NO.1
    北航软工优秀作业汇总
    Alpha阶段评审结果和意见反馈
    转会候选人名单
    人员转会流程
    关于团队项目阶段目标的说明
    2021年软工-热身阅读作业
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3442382.html
Copyright © 2020-2023  润新知