从其他线程停止线程

时间:2016-07-14 08:44:59

标签: c# multithreading

我在C#中使用多线程有点困难。

我只是激活线程:

        getMultiVarEnabled = true;
        Globals.readThread = new Thread(readMultipleVarForTextBoxes);
        Globals.readThread.IsBackground = true;
        Globals.readThread.Start();

内线:

        Globals.PIC.recievingMultiple = true;
        while (getMultiVarEnabled)   //  dodaj timeout
        { ... }
        Globals.PIC.recievingMultiple = false;
        Globals.readThread.Abort();

从我使用的主线程中停止线程:

        if (getMultiVarEnabled)
        {
            getMultiVarEnabled = false;     
            while (Globals.PIC.recievingMultiple);  
            Globals.readThread.Join();
            Globals.readThread = null;
        }

问题在于,有时(并非总是)我的程序会在线停止:

           while (Globals.PIC.recievingMultiple);

有人知道是什么导致这种错误发生吗?

祝你好运, 克里斯

2 个答案:

答案 0 :(得分:4)

你应该真的避免Thread.Abort()。如果给出一个线程的方法退出,线程将自动关闭。所以在你的线程中只需删除中止调用并离开方法。如果您需要预先退出该主题并希望通知它,请使用CancellationToken

此外,如果您想创建一些工作项,那应该由一个线程中的一个线程处理,而不是提供这些(也是不可变的)工作项的不可变列表(例如数组)。然后,线程本身可以创建在工作完成后返回的结果列表。也许你应该看看生产者消费者模式

使用将从不同线程操纵的共享状态总是导致难以调试的问题。不变性是你的朋友。

仅举例来说,Roslyn编译器内部使用所有不可变对象,immutable collections只是为了消除大多数出现的竞争条件。

答案 1 :(得分:3)

由于竞争条件,它很可能失败。我假设recievingMultiple在线程启动之前未初始化,因此默认为false

所以当你执行以下操作时:

while (Globals.PIC.recievingMultiple);  

...有可能是false,因此完全跳过while

使用AutoResetEvent; ManualResetEvent或至少Interlocked.CompareExchange; Interlocked.Read比纯变量更安全。

产生一个线程只是为了立即阻止它完成某种程度的失败线程的目的。