如何在线程休眠时中止线程

Posted

技术标签:

【中文标题】如何在线程休眠时中止线程【英文标题】:How to abort a thread when it is sleeping 【发布时间】:2011-04-26 16:12:02 【问题描述】:

我需要停止一个线程,但如果它应该休眠 8 秒,而我想中止它,它将继续休眠 8 秒,然后才停止。

【问题讨论】:

在睡眠期间或之后中止是否重要? 你考虑过唤醒它吗? IE。使用会迫使它脱离睡眠的东西? 中止线程是一个真的坏主意。见***.com/questions/1559255/… 而且(几乎总是)在线程中使用 Sleep() 是一个非常糟糕的主意。 这些人是对的;完全重新审视你的线程策略。休眠和中止线程几乎从来都不是正确的做法。把它们都放在一起是一个糟糕的主意。您应该有一个精心设计的解决方案,其中一个线程可以礼貌地请求另一个线程自行关闭,而另一个线程保证及时这样做。 【参考方案1】:

使用ManualResetEvent

ManualResetEvent mre=new ManualResetEvent(false);
//......
var signalled=mre.WaitOne(TimeSpan.FromSeconds(8));
if(!signalled)

    //timeout occurred

其他地方(在 8 秒结束之前):

mre.Set(); //unfreezes paused Thread and causes signalled==true

并允许未阻塞的线程优雅地终止。 Thread.Abort 是 evil and should be avoided。

【讨论】:

【参考方案2】:

您不能(安全地)在线程处于睡眠状态时中止它。您应该在阻塞完成后立即检查您的中止条件,然后退出。

无论如何,这在大多数情况下确实没有缺点,因为线程在阻塞时将使用很少的资源。

如果您必须尽快“中止”,则可以改为使用不同的阻塞机制。睡眠很少是正确的选择 - 等待句柄可能能够提供相同的功能,并为其他线程提供一种方法来发出信号,表明它应该立即停止阻塞。

【讨论】:

【参考方案3】:

考虑使用System.Timers.Timer 类。这是一个可以在需要时停止的计时器。

你可以找到一些很好的说明here

【讨论】:

【参考方案4】:

使用 AutoResetEvent timed Wait 而不是 Sleep,当您希望中断等待线程时使用 Set 向 AutoResetEvent 发出信号,否则计时器将到期。

【讨论】:

以上是关于如何在线程休眠时中止线程的主要内容,如果未能解决你的问题,请参考以下文章

在片段分离时中止加载 AsyncTaskLoader

如何使用 p/invoke 终止从 C# 调用的 C++ 函数

如何检查线程是不是处于休眠状态?

如何在 Windows DLL 中正确实现和关闭休眠线程

如何在线程休眠期间每尝试一定次数后记录错误?

如何在收到异步函数的回调之前使线程休眠?