什么是挂起线程?

4
< p > Thread.Abort()文档表示,如果:

< blockquote >

正在被终止的线程当前处于暂停状态。

这是什么情况?

例如,如果线程正在执行Thread.Sleep(1000)或正在等待WaitHandle,它是否被认为是“暂停”?


我认为它指的是过时的Thread.Suspend - Brad Christie
3个回答

6
从阅读文档中,我的解释是在这个上下文中,“suspended”并不涉及使用Thread.SleepWaitHandle的用法,而是指在使用过时的Thread.Suspend或等效的Windows APISuspendThread时遇到的线程状态。

在这个上下文中,一个被挂起的线程是指其执行被显式暂停(或挂起),即它的上下文不再被执行,但已被挂起以在稍后的某个时间恢复执行。
调试器主要使用此技术,并不建议将其用于同步操作。这在有关SuspendThread的MSDN文档中得到了澄清:

所以我猜这是你的方式表达普通等待、休眠或阻塞线程不算作“挂起”。但如果调试器挂起一个线程,然后另一个线程试图中止它...这可能会导致异常? - Qwertie
@Qwertie:是的,那是我对文档的理解(一个调试器或其他使用“暂停”线程能力的应用程序)。我已经更新了我的答案,直接回答了你的问题。谢谢。 - Jeff Yates

3

暂停的线程是因为调用了Thread.Suspend而被暂停的线程。

请参阅ThreadState枚举以获取线程可能处于的状态列表及其进入方式。


1

在这方面,文档相当贫乏。虽然不建议使用Thread.Abort,但在2.0及更高版本中,它要安全得多。它将安全地解除大多数.NET BCL阻塞调用,包括Thread.SleepWaitHandle.WaitOneMonitor.Enter等。我认为,在这种情况下,“挂起”的含义是一个被阻塞在其中一个这些调用内的线程。 我相信可以通过以下代码证明这一点。

static void Main(string[] args)
{
    var thread = new Thread(() => 
        {
            try
            {
                Console.WriteLine("Thread blocking");
                Thread.Sleep(Timeout.Infinite);
                Console.WriteLine("Thread unblocked");
            }
            catch (ThreadAbortException)
            {
                Console.WriteLine("ThreadAbortException");
            }
        });
    Console.WriteLine("Starting thread");
    thread.Start();
    Console.WriteLine("Waiting 1 second");
    Thread.Sleep(1000);
    Console.WriteLine("Aborting thread");
    thread.Abort();
    Console.WriteLine("Waiting for thread to end");
    thread.Join();
    Console.WriteLine("Thread ended");
    Console.ReadLine();
}

将对Thread.Sleep的调用替换为BCL中的其他阻塞调用,以查看哪些调用可以被Thread.Abort“poke”。

更新

我的原始解释显然是错误的。文档几乎明确告诉您应该是什么解释。

如果在已暂停的线程上调用Abort,则在调用Abort的线程中引发ThreadStateException,并将AbortRequested添加到正在中止的线程的ThreadState属性中。直到调用Resume,才会在暂停的线程中抛出ThreadAbortException。

我将继续保留我的答案,因为它与问题有关。


我认为你的解释是错误的。阅读 Thread.Abort 的文档,"suspended" 一词用于 "Resume" 意味着在已过时的 Thread.Suspend 中处于暂停状态时才会发生所描述的行为。 - Jeff Yates
是的,在仔细阅读那一部分后,它确实是用于“Thread.Resume”的上下文中。 - Brian Gideon
我决定保留我的答案,因为我认为它在某种程度上确实回答了问题的第二部分。我最初对文档的解释完全错误...很抱歉误导了大家。 - Brian Gideon
嗯,有趣的是 - Abort() 可以抛出 ThreadStateException 异常,但是当挂起的线程恢复时,它仍然会中止。尽管在未来某个未知的时间点执行请求的操作,但从方法中获得异常还是很奇怪的。+1 为了玩 :) - Qwertie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接