博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
编写高质量代码改善C#程序的157个建议——建议77: 正确停止线程
阅读量:5371 次
发布时间:2019-06-15

本文共 1707 字,大约阅读时间需要 5 分钟。

建议77: 正确停止线程

开发者总尝试对自己的代码有更多的控制。例如,“让那个还在工作的线程马上停止下来”。然而,并非我们想怎样就可以怎样的,这至少涉及两个问题。
第一个问题 正如线程不能立即启动一样,线程也并不是说停就停的。无论采用何种方式通知工作线程需要停止,工作线程都会忙完手头最紧要的活,然后在它觉得合适的时候退出。以最传统的Thread.Abort方法为例,如果线程当前正在执行的是一段非托管代码,那么CLR就不会抛出ThreadAbortException,只有当代码继续回到CLR中时,才会引发ThreadAbortException。当然,即便是在CLR环境中,ThreadAbortException也不会立即引发。
第二个问题 要正确停止线程,不在于调用者采取了什么行为(如最开始的Thread.Abort()方法),而更多依赖于工作线程是否能主动响应调用者的停止请求。大体机制是,如果线程需要被停止,那么线程自身就应该负责给调用者开放这样的接口:Cancled。线程在工作的同时,还要以某种频率检测Cancled标识,若检测到Cancled,线程自己才会负责退出。
FCL现在为我们提供了标准的取消模式:协作式取消(Cooperative Cancellation)。协作式取消的机制就是上文第二个问题中所提到的机制。下面是一个最基础的协作式取消的示例:

CancellationTokenSource cts = new CancellationTokenSource();  Thread t = new Thread(() =>    {          while (true)          {              if (cts.Token.IsCancellationRequested)              {                  Console.WriteLine("线程被终止!");                  break;              }              Console.WriteLine(DateTime.Now.ToString());              Thread.Sleep(1000);          }      });  t.Start();  Console.ReadLine();  cts.Cancel();

调用者使用CancellationTokenSource的Cancel方法通知工作线程退出。工作线程则以大约1000ms的频率一边工作,一边检查是否有外界传入的Cancel信号,若有这样的信号,则退出。可以看到,在正确停止线程的机制中,真正起到主要作用的是线程本身。示例中的工作代码比较简单,但足以说明问题。更复杂的计算式工作,也应该以这样的一种方式,妥善而正确地处理退出。
协作式取消中的关键类型是CancellationTokenSource。它有一个关键属性Token,Token是一个名为CancellationToken的值类型。CancellationToken继而进一步提供了布尔值的属性IsCancellationRequested作为需要取消工作的标识。CancellationToken还有一个方法尤其值得注意,那就是Register方法。它负责传递一个Action委托,在线程停止的时候被回调,使用方法如下:

cts.Token.Register(() =>{      Console.WriteLine("工作线程被终止了。");  });

本例使用Thread进行了演示,如果使用ThreadPool也是一样的模式,这里就不再赘述。后面还会讲到任务Task,它依赖于CancellationTokenSource和CancellationToken完成了所有的取消控制。

 

 

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

转载于:https://www.cnblogs.com/jesselzj/p/4742401.html

你可能感兴趣的文章
一些前台功能代码实现
查看>>
Centos
查看>>
CSS层叠样式表的层叠是什么意思(转自知乎)
查看>>
似乎在梦中见过的样子 (KMP)
查看>>
Codeforces Round #503 (by SIS, Div. 2) D. The hat
查看>>
ECharts 使用
查看>>
JSON和JavaScript对象
查看>>
Java基础加强总结(一)——注解(Annotation)
查看>>
enq: HW - contention等待事件
查看>>
dfs小练 【dfs】
查看>>
linux设备驱动归纳总结(十三):1.触摸屏与ADC时钟【转】
查看>>
rpcbind服务没法开启问题
查看>>
Java 数据类型
查看>>
Tomcat 安装错误
查看>>
private、 protected、 public、 internal 修饰符的访问权限
查看>>
Android学习记录01——Activity传值
查看>>
django 使用HttpResponse返回json数据为中文
查看>>
java虚拟机(三)-- 虚拟机类加载机制
查看>>
delphi从dll中调用图片资源
查看>>
IIS MIME的 映射 网站有些类型的文件不能通过网页访问
查看>>