Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 终止线程时,独立线程中任务的行为_C#_Multithreading_Parallel.foreach - Fatal编程技术网

C# 终止线程时,独立线程中任务的行为

C# 终止线程时,独立线程中任务的行为,c#,multithreading,parallel.foreach,C#,Multithreading,Parallel.foreach,我有一个特殊的线程设置和Parallel.Foreach:在一个单独的线程中执行Parallel.Foreach循环。调用函数Abort()可能会中止线程。我遇到了奇怪的行为:多次抛出ThreadAbortException。有人能解释一下这里发生了什么,什么是好的解决办法吗 系统: Visual Studio 2017 C#7.0 .Net 4.6.1 代码如下 static void Main(string[] args) { //Start the new Th

我有一个特殊的线程设置和
Parallel.Foreach
:在一个单独的线程中执行
Parallel.Foreach
循环。调用函数
Abort()
可能会中止
线程。我遇到了奇怪的行为:多次抛出
ThreadAbortException
。有人能解释一下这里发生了什么,什么是好的解决办法吗

系统:

  • Visual Studio 2017
  • C#7.0
  • .Net 4.6.1
代码如下

static void Main(string[] args)
    {
        //Start the new Thread
        Thread workerThread = new Thread(Program.TestVoid);
        workerThread.Name = "My WorkerThread";
        workerThread.Start();

        //wait
        Thread.Sleep(1000);

        //abort thread
        workerThread.Abort();
    }

    public static void TestVoid()
    {
        bool[] liBools = new bool[10000];

        Parallel.For(0, liBools.Length, idx =>
        {
            liBools[idx] = idx == 9998;
        });

        try
        {
            Parallel.ForEach(liBools, myBool =>
            {
                try
                {
                    //do something
                    Thread.Sleep(1000);
                }
                catch (Exception ex) //Thread Abort Exception get caught
                {

                }
            });
        }
        catch (OperationCanceledException ex)
        {

        }
        catch (ThreadAbortException ex) //Thread Abort Exception get caught
        {

        } //here arises another ThreadAbortException
        finally
        {
            source.Dispose();
        }
        string s = "ready";
    }
如果查看,您将看到它的功能是抛出
ThreadAbortException
。如果这不是您想要的,请不要使用
Thread.Abort
。通常,您应该通过优雅地完成/返回整个调用堆栈来退出线程,而不是调用
thread.Abort
。如果必须调用
Thread.Abort
,则应准备好处理随之发生的异常。

如果查看,您将看到它的功能是抛出
ThreadAbortException
。如果这不是您想要的,请不要使用
Thread.Abort
。通常,您应该通过优雅地完成/返回整个调用堆栈来退出线程,而不是调用
thread.Abort
。如果必须调用
Thread.Abort
,则应准备好处理随之发生的异常

我得到一个奇怪的行为:多次抛出
ThreadAbortException

这是该异常的正常行为:

当调用Abort方法销毁线程时,公共语言运行库抛出ThreadAbortException。ThreadAbortException是一个可以捕获的特殊异常,但它将在catch块结束时自动再次引发。当引发此异常时,运行库在结束线程之前执行所有finally块。因为线程可以在finally块中执行无界计算,或者调用thread.ResetAbort来取消中止,所以不能保证线程会结束。如果要等待中止的线程结束,可以调用thread.Join方法。Join是一个阻塞调用,在线程实际停止执行之前不会返回。()

什么是好的解决方案

您可以使用
Thread.ResetAbort()
在此时取消中止,但如果您不调用
Thread.Abort()
,几乎总是会更好。可取消的
任务
s和检查易变的“请立即停止”布尔值是两种选择。其他可能适用于您的用例
Thread.Abort()
应仅保留在按下红色大警报按钮的情况下,如果需要的话

我得到一个奇怪的行为:多次抛出
ThreadAbortException

这是该异常的正常行为:

当调用Abort方法销毁线程时,公共语言运行库抛出ThreadAbortException。ThreadAbortException是一个可以捕获的特殊异常,但它将在catch块结束时自动再次引发。当引发此异常时,运行库在结束线程之前执行所有finally块。因为线程可以在finally块中执行无界计算,或者调用thread.ResetAbort来取消中止,所以不能保证线程会结束。如果要等待中止的线程结束,可以调用thread.Join方法。Join是一个阻塞调用,在线程实际停止执行之前不会返回。()

什么是好的解决方案

您可以使用
Thread.ResetAbort()
在此时取消中止,但如果您不调用
Thread.Abort()
,几乎总是会更好。可取消的
任务
s和检查易变的“请立即停止”布尔值是两种选择。其他可能适用于您的用例
Thread.Abort()
应仅保留在按下红色大警报按钮的情况下,如果需要的话