1

最近,我终于能够使一个单独的线程工作。现在我正在尝试掌握同步。

据我所知,暂停线程ThreadName.Suspend()并不是一个好主意。首先,我使用While循环来阻塞线程。后来我注意到这会消耗资源,所以现在我试图用AutoResetEvent.

这是一些代码(告诉我是否完整的代码):

private void combTester(object sender, EventArgs e)//happens in a timer, because it manipulates the GUI
{
    if (!timer2Block)
    {
        //stuff happens
        genBlock = false;//unblocks the thread
        timer2Block = true;//blocks itself
        //debugging stuff happens
    }
    if (done)
        timer2.Enabled = false;
}

private void combGenerator(int currEl, int begVal)
{
    //setting a variable
    for (int c = begVal; c <= currEl + totalCells - maxCells; c++)
    {
        while (genBlock && !abortTime)
        {
            if (abortTime)
                return;
        }
        genBlock = true;//blocks itself
        //some recursive stuff happens,
        //because of which I was forced to use a thread instead of timers
    }
}

我尝试了不同的地方来放置Wait()Set()方法,但是踏板和计时器都被阻塞了,我不知道如何调试程序。

那么,我怎样才能用 替换While循环AutoResetEvent

4

2 回答 2

1

如果您想要对工作线程进行“暂停”控制,那么您应该使用ManualResetEvent: 保持事件信号,并在您希望线程暂停时重置它:

private void combGenerator(int currEl, int begVal)
{
    for (int c = begVal; c <= currEl + totalCells - maxCells; c++)
    {
        manualResetEvent.WaitOne();
        // do stuff
    }
}

您现在可以combGenerator通过相应manualResetEvent.Reset()的操作来暂停/取消暂停线程manualResetEvent.Set()

这可以进一步扩展为通过抛出另一个信号来包含“中止”信号ManualResetEvent(这也可以是一个AutoResetEvent,但因为它只会在区别不重要时才会做某事):

    var events = new[] { abortEvent, pauseEvent }; // order MATTERS!
    for (int c = begVal; c <= currEl + totalCells - maxCells; c++)
    {
        var index = WaitHandle.WaitAny(events);
        if (index == 0) {
            // abort!
        }

        // do stuff
    }

这里的魔法发生在里面WaitAny。此方法将等待任何事件发出信号,并返回发出信号的事件中的最小索引(如果超过一个)。这非常重要,因为它可以让我们确定是否应该中止。

在正常操作期间abortEvent不会发出信号并且pauseEvent会发出信号,所以WaitAny会立即返回1。如果pauseEvent被重置,WaitAny则将阻塞,直到再次发出事件之一信号。如果abortEvent发出信号,则WaitAny返回0,这是退出的提示。

于 2013-09-28T21:27:35.403 回答
0

您可以使用另一个标志来检查它是否是递归调用,根据它您可以决定继续还是等待。

例子:

static int recCount = 0;
private void combGenerator(int currEl, int begVal)
{
        //setting a variable
        for (int c = begVal; c <= currEl + totalCells - maxCells; c++)
        {
            while (genBlock && !abortTime and recCount < 1)
            {
                if (abortTime)
                    return;
            }
            genBlock = true;//blocks itself
            recCount ++;
            //some recursive stuff happens,
            //because of which I was forced to use a thread instead of timers
          //after all the stuff is done
        recCount--;
    }
}
于 2013-09-28T21:21:58.443 回答