gpt4 book ai didi

c# - 等待事件引发线程取消

转载 作者:行者123 更新时间:2023-11-30 16:59:09 25 4
gpt4 key购买 nike

我有一个通过引发事件来报告进度的工作线程。

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 事件。

有没有办法很好地解决这个问题,还是从一开始就设计得很糟糕?我当前的解决方案依赖于 UI 在处理工作人员之前等待 WorkFinished 事件。

最佳答案

在评论中您暗示您可以使用 await(甚至在 .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;
}
}

(快速拍打在一起。)注意,所有等待操作都使用 await。他们在不中断您的控制流的情况下释放 UI 线程。

另请注意,MyWorker 可协作取消。它对 UI 一无所知。

关于c# - 等待事件引发线程取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24242607/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com