最近,我终于能够创建一个单独的线程了。现在我正在尝试掌握同步。
据我所知,暂停一个帖子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
?
答案 0 :(得分: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
,这是退出的提示。
答案 1 :(得分: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--;
}
}