是否使用CurrentThread.Abort()方法终止当前线程?

15

我看过许多类似以下这样的线程过程的示例。

    private void ThreadProc()
    {
        while (serviceStarted)
        {
            // do some work

            Thread.Sleep(new TimeSpan(0, 0, 5));
        }

        Thread.CurrentThread.Abort();
    }

在结束时是否真的需要使用 Abort()

有许多反对调用 Abort() 的论点:

  1. 一旦过程退出——预期它已经完成了自我清理。
  2. 调用 Abort() 将会抛出一个异常,相比直接退出过程,这通常会消耗更多资源。

我想了解为什么这是或不是一个好的做法的解释。

5个回答

6
调用Thread.Abort()会引发异常,如果您正在编写将被重用的代码(或基本库的一部分),其他开发人员很难处理ThreadAbortExcpetion。在这篇关于可靠性最佳实践的文章中有解释。
我一直听说调用Thread.Join()是更好的方法,如果您可以等待线程完成处理。
我不知道是否有人认为这是一个好习惯。它可能会导致死锁(因为当您抛出异常时,未托管的资源没有得到适当清理)。
这里是另一篇文章,介绍了处理此问题的其他方法。

3

一旦循环退出,线程将自行终止。无需中止线程。

CurrentThread.Abort 不仅是多余的,而且真正有害,因为它引发了 ThreadAbortException。如果另一个线程尝试Join()你的服务循环线程,它将不必要地处理异常。最好的方法就是删除 CurrentThread.Abort() 这一行。


1

在自己的线程上调用Abort()是安全的,但除此之外,通常应该避免这样做,因为你无法确定其他线程是否会优雅地终止。在许多情况下,你不需要中止线程。只需让它完成,它就会被回收。


0

有趣的问题。但我建议不要这样做,因为这样的语句会阻止方法被轻松地重复使用。


0

当线程没有进一步的工作要执行时,它会自然地自我终止:当它正在执行的逻辑完成时。

Thread.Abort() 会在当前线程上引发 ThreadAbortException,其明确目的是快速终止线程上的所有执行。这是 .NET 中特殊的异常之一,它是“无法捕获”的:您可以编写 catch 块,但是异常将在 catch 块完成后继续被抛出。这确保了没有办法通过后续用户代码停止中止线程的指令。

通常认为调用 Thread.Abort() 是不好的做法,因为有更优雅的方式来终止您正在执行的逻辑。使用 CancellationToken 更好地处理取消。


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