繁体   English   中英

中止线程时单独线程中任务的行为

[英]Behaviour of tasks in separate thread on aborting the thread

我使用线程和Parallel.Foreach了特殊设置:在一个单独的线程中,执行了Parallel.Foreach循环。 通过调用函数Abort()可能会中止Thread 我得到奇怪的行为:多次抛出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

这是该异常的正常行为:

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

什么是一个好的解决方案

您可以在此时使用Thread.ResetAbort()取消中止操作,但是如果不调用Thread.Abort()几乎总是更好。 可取消Task和检查易失性“请立即停止”布尔值是两种选择。 其他可能适用于您的用例。 Thread.Abort()仅应在按红色提示按钮的情况下保留,如果那样的话。

如果查看Thread.Abort文档,您会发现它的功能是引发ThreadAbortException 如果那不是您想要的,请不要使用Thread.Abort 通常,您应该通过从线程的整个调用堆栈正常完成/返回而不是调用Thread.Abort退出线程。 如果必须调用Thread.Abort ,则应该准备处理随之发生的异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM