我有一个工作线程,它通过引发事件来报告进度。
private volatile bool canRun;
public void Run()
{
for (int i = 0; i < count && canRun; i++)
{
// do stuff
OnProgressMade((float)i / (float)count);
}
OnWorkFinished();
}
public void Cancel()
{
canRun = false;
// wait for the thread to finish
}在Cancel方法中,我希望等待线程完成。否则,当线程仍在“做事情”时,可能有人调用Cancel,然后立即调用Dispose。如果我使用Join,可能会出现死锁- UI等待线程取消,线程等待UI处理ProgressMade事件。
是否有办法很好地解决这个问题,还是从一开始就设计得很糟糕?我的当前解决方案依赖于在释放工作人员之前等待WorkFinished事件的UI。
发布于 2014-06-16 15:20:10
在注释中,您暗示您可以使用“等待”(即使在.NET 4.0上也是可能的)。看起来可能是这样的:
MyWorker w;
CancellationTokenSource cts;
void OnStart(eventargs bla bla) {
cts = new ...();
w = new ...(cts.Token);
}
void OnCancel(eventargs bla bla) {
cts.Cancel();
await w.WaitForShutdown();
MsgBox("cancelled");
}我们需要让MyWorker合作:
class MyWorker {
CancellationToken ct = <from ctor>;
TaskCompletionSource<object> shutdownCompletedTcs = new ...();
public void Run()
{
for (int i = 0; i < count && !ct.IsCancellationRequested; i++)
{
// do stuff
OnProgressMade((float)i / (float)count);
}
//OnWorkFinished(); //old
shutdownCompletedTcs.SetResult(null); //new, set "event"
}
public Task WaitForShutdown() {
return shutdownCompletedTcs.Task;
}
}(迅速拍打在一起。)注意,所有等待操作都在等待。它们在不中断控制流的情况下释放UI线程。
还请注意,MyWorker是可以协作取消的。它不知道任何有关UI的信息。
https://stackoverflow.com/questions/24242607
复制相似问题