zoukankan      html  css  js  c++  java
  • .NET:如何让线程支持超时?

    背景

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

    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 给回收,有一点需要说明的是:线程的未处理异常会导致应用程序的终止,一个线程的异常不会自动冒泡到其它线程。

    备注

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

  • 相关阅读:
    Verilog HDL刷题笔记(06)(Circuit-Combinational Logic-Arithmetic Circuit)
    Verilog HDL刷题笔记(05)(Circuit-Combinational Logic-Multiplexers)
    Verilog HDL刷题笔记(04)(Circuit-Combinational Logic-Basic Gates)
    Verilog HDL刷题笔记(03)
    Verilog HDL刷题笔记(02)
    Verilog HDL刷题笔记(01)
    某点评 手机验证码自动登录
    线程锁实现多线程读取mongo 数据库库
    Python mongo 快速读取
    正方教務管理系統RSA 加密
  • 原文地址:https://www.cnblogs.com/happyframework/p/3440877.html
Copyright © 2011-2022 走看看