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
如何退出ThreadState.WaitSleepJoin C#?_C#_Multithreading - Fatal编程技术网

如何退出ThreadState.WaitSleepJoin C#?

如何退出ThreadState.WaitSleepJoin C#?,c#,multithreading,C#,Multithreading,这是我的密码: protected AutoResetEvent _waitHandle = new AutoResetEvent(false); protected virtual void ThreadProc() { while (WorkState != WorkStates.Paused) { while (HasWork()) { if (WorkState == WorkStates.Paused || !D

这是我的密码:

protected AutoResetEvent _waitHandle = new AutoResetEvent(false);

protected virtual void ThreadProc()
{
    while (WorkState != WorkStates.Paused)
    {
        while (HasWork())
        {
            if (WorkState == WorkStates.Paused || !DoWork())
                    break;
        }
        _waitHandle.WaitOne();
    }
}
所以,当线程启动时,它检查是否有作业要做,完成后,它将等待设置_waitHandle。这里是wake函数,当新任务进入时调用它

    public void Wake()
    {
        if ((_thread.ThreadState & ThreadState.Unstarted) == ThreadState.Unstarted)
            _thread.Start();
        else if (_thread.IsAlive)
            _waitHandle.Set();
    }
其中CreateThread如下所示:

    protected virtual void CreateThread(bool start = false)
    {
        _thread = new Thread(ThreadProc) { IsBackground = true };
        _thread.Name = GetType().Name;
        if (start)
            _thread.Start();
    }
这段代码在大多数情况下都可以正常工作,但有时却不行。通常,当线程正在等待_waitHandle时,该线程处于活动状态,其状态更改为WaitSleepJoin。在本例中,调用_waitHandle.set()将使其再次激活。但是,有时它不工作,尽管状态相同(即线程处于活动状态,线程状态为WaitSleepJoin)

它似乎没有在_waitHandle.WaitOne()处等待,因为调用_waitHandle.set()不会触发。使线程再次循环的唯一方法是调用CreateThread(true)。问题是如何知道线程是否正在等待_waitHandle

下面是我在尝试处理这个问题时所做的一些研究,但是CreateThread()被调用的次数太多了

    public void Wake()
    {
        if ((_thread.ThreadState & ThreadState.Unstarted) == ThreadState.Unstarted)
            _thread.Start();
        else if ((_thread.ThreadState & ThreadState.WaitSleepJoin) == ThreadState.WaitSleepJoin)
        {
            if (!_waitHandle.WaitOne(0))
                _waitHandle.Set();
            else
                CreateThread(true);
        }
        else if (_thread.IsAlive)
            _waitHandle.Set();
    }

我不明白的是,如果_thread.IsAlive为true,且其线程状态为WaitSleepJoin,那么线程在哪里(我确保线程中也没有活动工作)?如何唤醒它?

出于好奇,不使用TPL的原因是什么?在唤醒方法(问题的最后一个代码段)中,为什么要创建更多线程对象并启动它们并将它们分配给_thread字段?这样做的目的是什么?它看起来非常错误…很可能在原始代码中创建了两个或多个运行ThreadProc方法的线程。这意味着,您还有两个或多个线程在等待_waitHandle。记住,waitHandle是一个自动resetEvent。如果发出自动重置事件的信号,则只会唤醒一个线程,然后自动重置自动重置事件(因此而得名)。在此AutoResetEvent上等待的任何其他线程都将继续等待。也许当你认为设置waitHandle并没有唤醒你的线程时,它只是唤醒了另一个线程,而不是你所看到的那个线程……关于为什么不使用TPL的问题,这来自于遗留代码和我的遗留思想,但如果有人能帮我将此代码翻译成TPL,我愿意切换。@elgonzo,正如我在问题中所说的,在WaitSleepJoin状态下添加CreateThread是在它卡住时重新启动它的唯一方法。这实际上是我问这个问题的主要原因。