Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么CLR重新抛出ThreadAbortException?_C#_Multithreading_Clr_Threadabortexception - Fatal编程技术网

C# 为什么CLR重新抛出ThreadAbortException?

C# 为什么CLR重新抛出ThreadAbortException?,c#,multithreading,clr,threadabortexception,C#,Multithreading,Clr,Threadabortexception,我从《Windows上的并发编程》一书中获得了以下代码: 我想知道为什么CLR重新抛出ThreadAbortException?它一直这样做,直到我调用“Thread.ResetAbort()”。第二,是否有任何其他系统定义的异常,从CLR得到特殊处理?这是一个特殊异常,请参见备注。据我所知,发生这种情况的原因是.Net使您能够在线程关闭之前完成任何清理工作 有关管道的详细信息,请参见以下内容: 我想知道为什么CLR重新抛出ThreadAbortException 因为线程正在中止。人们总是处理

我从《Windows上的并发编程》一书中获得了以下代码:

我想知道为什么CLR重新抛出ThreadAbortException?它一直这样做,直到我调用“Thread.ResetAbort()”。第二,是否有任何其他系统定义的异常,从CLR得到特殊处理?

这是一个特殊异常,请参见备注。据我所知,发生这种情况的原因是.Net使您能够在线程关闭之前完成任何清理工作

有关管道的详细信息,请参见以下内容:

我想知道为什么CLR重新抛出ThreadAbortException

因为线程正在中止。人们总是处理所有异常,即使这样做是危险的。如果一个错误日志例程,比如说,让一个本应被永远销毁的线程保持活着,那将是很奇怪的,不是吗

是否存在任何其他系统定义的异常,这些异常会得到CLR的特殊处理


是的,有几个。例如,堆栈外和内存外异常也有特殊的行为

谢谢你的回答。我只是想问一下,既然我知道这种行为,是否建议在“ThreadAbortException”try catch块中封装基于线程的代码?由于异常无论如何都将被重新抛出,该行为可能会让不知道该异常行为方式的人感到惊讶。@PawanMishra:我想到了两条好规则。第一个是“永远不要中止线程”。正常终止线程;如果你做不到,就把整个过程都干掉。中止线程是非常危险的。第二,“永远不要处理无法处理的异常。”当线程被中止时,没有什么好的事情可以做。因为你永远不会中止线程,如果你这样做了,也永远不会处理异常,所以编写catch块有点毫无意义,对吧?你在问OPs第二个问题:是否有“系统定义的异常[从CLR]得到特殊处理”?有线程/进程状态会导致事情发生,但我不认为异常本身就是特例,正如可以看到的那样。显然,我不得不跳过一两个环,让我的代码自己(重新)抛出一个
ThreadAbortException
,可能还有其他异常在抛出时会做一些有趣的事情,但这些异常似乎没有。(真正的堆栈溢出和中止的线程状态显然有特殊处理。)还要注意,调用thread.ResetAbort()的代码需要特殊权限才能执行此操作。因此,如果您正在托管CLR或创建AppDomain,则可以使用此功能使中止线程更具确定性。
void Main()
{
    try
    {
        try
        {
            Console.WriteLine("Inside Main Method");
            Thread.CurrentThread.Abort();
        }
        catch(ThreadAbortException)
        {
            Console.WriteLine("Inside First Catch");
            // Trying to swallow but CLR throws it again....
        }
    }
    catch(ThreadAbortException)
    {
        Console.WriteLine("Inside Second Catch");
        //Thread.ResetAbort();
    }
}