栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

有关在.NET中干净终止线程的问题

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

有关在.NET中干净终止线程的问题

不幸的是,可能没有更好的选择。这实际上取决于您的特定情况。这个想法是在安全点优雅地停止线程。这就是为什么

Thread.Abort
不好的原因所在。因为它不能保证在安全点发生。通过在代码上添加停止机制,可以有效地手动定义安全点。这称为合作取消。基本上有4种广泛的机制可以做到这一点。您可以选择最适合您的情况。

轮询停止标志

您已经提到了此方法。这是很普通的一个。定期检查算法中安全点处的标志,并在收到信号时纾困。标准方法是标记变量

volatile
。如果这不可能或不方便,则可以使用
lock
。请记住,您不能标记局部变量,
volatile
因此,例如,如果lambda表达式是通过闭包捕获的,那么您将不得不采用另一种方法来创建所需的内存屏障。此方法不需要说很多其他内容。

在TPL中使用新的取消机制

这类似于轮询停止标志,除了它使用TPL中的新取消数据结构。它仍然基于协作取消模式。您需要获取

CancellationToken
和定期检查
IsCancellationRequested
。要请求取消,你会打电话
Cancel
CancellationTokenSource
最初提供的令牌。您可以使用新的取消机制做很多事情。您可以在此处了解更多信息。

使用等待句柄

如果您的工作线程需要在特定间隔内等待或在其正常操作期间等待信号,则此方法很有用。你可以

Set
一个
ManualResetEvent
,例如,让线程知道是时候停下来。您可以使用该
WaitOne
函数测试事件,该函数返回一个
bool
指示事件是否已发出信号的指示。该
WaitOne
有一个参数,指定了多少时间等待调用返回如果事件没有在该时间量信号。您可以使用此技术代替
Thread.Sleep
并同时获得停止指示。如果
WaitHandle
线程可能还要等待其他实例,这也很有用。您可以一次呼叫
WaitHandle.WaitAny
以等待任何事件(包括停止事件)。使用事件比打电话更好
Thread.Interrupt
因为您可以更好地控制程序的流程(
Thread.Interrupt
抛出异常,所以您必须策略性地放置
try-catch
块以执行任何必要的清除)。

特殊场景

有几种一次性方案具有非常专门的停止机制。枚举所有这些绝对超出了此答案的范围(没关系,这几乎是不可能的)。我的意思很好的例子是

Socket
课堂。如果线程被阻塞在通话过程中
Send
Receive
则调用
Close
将中断对任何阻塞调用它是在有效地疏通它的插座。我确信BCL中还有其他几个类似的技术可以用来解除线程阻塞的区域。

通过中断线程

Thread.Interrupt

这样做的好处是它很简单,您不必专注于向代码中撒一些东西。缺点是您几乎无法控制算法中安全点的位置。原因是因为

Thread.Interrupt
通过在一个固定的BCL阻止调用中注入异常来起作用。这些措施包括
Thread.Sleep
WaitHandle.WaitOne
Thread.Join
等,所以你必须要聪明在哪里放置它们。但是,在大多数情况下,算法会指示它们的去向,而通常情况下这还是很好的,尤其是如果您的算法将大部分时间都用在了这些阻塞调用之一中时。如果您的算法未在BCL中使用阻塞调用之一,则此方法将对您不起作用。这里的理论
ThreadInterruptException
是只能从.NET等待调用生成,因此很
可能
在安全点。至少您知道该线程不能处于非托管代码中或无法脱离关键部分,而使悬挂的锁处于获取状态。尽管这种方法具有较小的侵入性,但
Thread.Abort
我仍然不鼓励使用它,因为尚不清楚哪个调用能够响应它,并且许多开发人员将不熟悉它的细微差别。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/378278.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号