C# 线程终止和 Thread.Abort()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2251964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:47:03  来源:igfitidea点击:

C# Thread Termination and Thread.Abort()

c#.netmultithreading

提问by user101375

In MSDN, the description of the Thread.Abort() method says: "Calling this method usuallyterminates the thread."

在 MSDN 中,对 Thread.Abort() 方法的描述说:“调用此方法通常会终止线程。”

Why not ALWAYS?

为什么不总是?

In which cases it doesn't terminate the thread?

在哪些情况下它不会终止线程?

Are there any other possibility to terminate threads?

还有其他可能终止线程吗?

回答by John Feminella

Why not ALWAYS? In which cases it doesn't termenate the thread?

为什么不总是?在哪些情况下它不会终止线程?

For starters, a thread may catch a ThreadAbortExceptionand cancel its own termination. Or it could perform a computation that takes forever while you're trying to abort it. Because of this, the runtime can't guarantee that the thread will always terminate after you ask it to.

对于初学者来说,一个线程可以捕获 aThreadAbortException并取消它自己的终止。或者它可以执行一个在你试图中止它时需要永远的计算。因此,运行时不能保证线程在您要求之后总是会终止。

ThreadAbortExceptionhas more:

ThreadAbortException有更多的:

When a call is made to the Abort method to destroy a thread, the common language runtime throws a ThreadAbortException. ThreadAbortException is a special exception that can be caught, but it will automatically be raised again at the end of the catch block. When this exception is raised, the runtime executes all the finally blocks before ending the thread. Since the thread can do an unbounded computation in the finally blocks, or call Thread.ResetAbort()to cancel the abort, there is no guarantee that the thread will ever end.

当调用 Abort 方法来销毁线程时,公共语言运行时会引发 ThreadAbortException。ThreadAbortException 是一种可以被捕获的特殊异常,但它会在 catch 块结束时自动再次引发。引发此异常时,运行时会在结束线程之前执行所有 finally 块。由于线程可以在 finally 块中进行无限计算,或者调用Thread.ResetAbort()取消中止,因此不能保证线程会永远结束。

You don't need to Abort()a thread manually. The CLR will do all of the dirty work for you if you simply let the method in the thread return; that will end the thread normally.

您不需要Abort()手动创建线程。如果您只是让线程中的方法返回,CLR 将为您完成所有繁重的工作;这将正常结束线程。

回答by Andy Shellam

I've had cases where the thread has been too busy to hear the Abort() call, which usually results in a ThreadAbortingException being thrown to my code.

我遇到过线程太忙而无法听到 Abort() 调用的情况,这通常会导致向我的代码抛出 ThreadAbortingException。

回答by Asad

What if a thread is holding a lock and is aborted / killed ? Resources remain stuck

如果线程持有锁并被中止/杀死怎么办?资源卡住了

It works fine when when a thread calls abort itself but not by other thread. Abort, forcefully terminates the affected thread even if it has not completed its task and provides no opportunity for the cleanup of resources

当一个线程调用 abort 本身而不是其他线程时,它工作正常。中止,强制终止受影响的线程,即使它尚未完成其任务并且不提供清理资源的机会

reference MSDN

参考MSDN



see: Managed Threading Best Practices

请参阅: 托管线程最佳实践

回答by Brian Rasmussen

Thread.Abort()injects a ThreadAbortExceptionon the thread. The thread may cancel the request by calling Thread.ResetAbort(). Also, there are certain code parts, such as finallyblock that will execute before the exception is handled. If for some reason the thread is stuck in such a block the exception will never be raised on the thread.

Thread.Abort()ThreadAbortException在线程上注入 a 。线程可以通过调用取消请求Thread.ResetAbort()。此外,还有某些代码部分,例如finally将在处理异常之前执行的块。如果由于某种原因线程卡在这样的块中,线程将永远不会引发异常。

As the caller has very little control over the state of the thread when calling Abort(), it is generally not advisable to do so. Pass a message to the thread requesting termination instead.

由于调用者在调用 时对线程状态的控制很少Abort(),因此通常不建议这样做。将消息传递给请求终止的线程。

回答by Pontus Gagge

OT: For a comprehensive, language-agnostic, questionably useful and darned funny take on concurrency, see Verity Stob!

OT:有关并发性的全面的、与语言无关的、有疑问的有用且该死的有趣观点,请参阅Verity Stob

回答by Rob Fonseca-Ensor

ThreadAborts will not occur inside a finally block or between BeginCriticalRegionand EndCriticalRegion

ThreadAborts 不会发生在 finally 块内或BeginCriticalRegionEndCriticalRegion之间

回答by erikkallen

Because you can catch the ThreadAbortExceptionand call Thread.ResetAbortinside the handler.

因为您可以在处理程序中捕获ThreadAbortException和调用Thread.ResetAbort

回答by Eric Lippert

In which cases it doesn't terminate the thread?

在哪些情况下它不会终止线程?

This question is a duplicate.

这个问题是重复的。

What's wrong with using Thread.Abort()

使用 Thread.Abort() 有什么问题

Are there any other posibility to terminate threads?

还有其他终止线程的可能性吗?

Yes. Your problem is that you should never start up a thread that you cannot tell politely to stop, and it stops in a timely manner. If you are in a situation where you have to start up a thread that might be (1) hard to stop, (2) buggy, or worst of all (3) hostile to the user, then the right thing to do is to make a new process, start the thread in the new process, and then terminate the processwhen you want the thread to go down. The only thing that can guarantee safe termination of an uncooperative thread is the operating system taking down its entire process.

是的。你的问题是你永远不应该启动一个你不能礼貌地停止的线程,它会及时停止。如果您必须启动一个线程,而该线程可能 (1) 难以停止,(2) 有问题,或者最糟糕的是 (3) 对用户怀有敌意,那么正确的做法是让一个新的进程,在新的进程中启动线程,然后在想要线程down掉的时候终止进程。唯一可以保证不合作线程安全终止的是操作系统取消其整个进程。

See my excessively long answer to this question for more details:

有关更多详细信息,请参阅我对这个问题的过长回答:

Using lock statement within a loop in C#

在 C# 中的循环中使用 lock 语句

The relevant bit is the bit at the end where I discuss what the considerations are regarding how long you should wait for a thread to kill itself before you abort it.

相关的部分是最后的部分,我讨论了关于在中止线程之前应该等待线程自行终止多长时间的注意事项。

回答by jovain

FileStream.Read()to a named pipe that is currently not receiving anything (read call blocks while waiting for incoming data) will not respond to Thread.Abort(). It remains inside the Read()call.

FileStream.Read()到当前未接收任何内容的命名管道(在等待传入数据时读取调用块)将不会响应Thread.Abort(). 它保留在Read()调用中。

回答by Colin

I can't seem to abort a thread that is stuck in a loop:

我似乎无法中止陷入循环的线程:

//immortal
Thread th1 = new Thread(() => { while (true) {}});

I can however abort the thread if sleeps during the loop:

但是,如果在循环期间休眠,我可以中止线程:

//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});