我正在尝试创建一个cancel-method,通过阻止调用者直到它来确保Task正常停止。
由于某些原因我遇到了僵局,我认为这是因为cancel.Set()
发生在cancel.WaitOne()
之前,然后等待另一个 cancel.Set()
,这不会来。
我想知道如何解决这个僵局。
这是实际代码,剥离了业务逻辑:
ManualResetEvent cancel = new ManualResetEvent(true);
Queue<string> queue;
bool run;
public void Start()
{
run = true;
ThreadPool.QueueUserWorkItem(Work);
}
public void Cancel()
{
if (!run)
{
return;
}
cancel.Reset();
run = false;
Requests.Clear();
if (queue != null)
queue.Clear();
cancel.WaitOne();
}
private void Work(object state)
{
//fill queue depending on requests
while (queue.Any() && Requests.Any() && run)
{
//fill queue some more recursively
//remove requests as they are processed
}
//BUG: Deadlock
cancel.Set();
}
如你所见,这几乎是我之前发布的内容。 (无论是我还是盲人)
更新
我结束了这样的任务:
Task activeItem;
bool run;
public void Start()
{
if(run)
return;
run = true;
activeItem = Task.Factory.StartNew(Work);
}
public void Cancel()
{
if (!run)
{
return;
}
run = false;
Requests.Clear();
if (queue != null)
queue.Clear();
activeItem.Wait(500);
}
private void Work()
{
//fill queue depending on requests
while (queue.Any() && Requests.Any() && run)
{
//fill queue some more recursively
//remove requests as they are processed
}
}
通过向任务添加超时我发现了一个非常奇怪的行为:整个Cancel-Method似乎阻止了Work() - 线程/任务作为一个整体。只有在Cancel()完成后,Work() - Thread才会继续。通过UI线程调用取消,这怎么可能?