【发布时间】:2021-03-29 06:50:07
【问题描述】:
最后在cmets后加
我有一个运行时间相当长的 Windows 窗体。所以我想我会让它异步。
因为有时操作者不想等到它完成,所以我给机会取消任务:
private CancellationTokenSource = new CancellationTokenSource();
private async Task<TResult> DoLongProcessingAsync(CancellationToken token)
{
// do some long async processing; allow cancelling
await Task.Delay(TimeSpan.FromSeconds(30), token);
return new TResult() {...};
}
public async void ButtonStart_Clicked(object sender, ...)
{
this.buttonStart.Enabled = false;
this.ShowBusy(true);
await this.DoLongProcessing(this.cancellationTokenSource.Token);
this.ShowBusy(false);
this.buttonStart.Enabled = true;
}
现在假设操作员在 DoLongProcessingAsync 完成之前关闭了表单。
private async void OnFormClosing(object sender, ...)
{
bool closingAlloged = this.AskOperatorIfClosingAllowed();
if (closingAllowed)
{
this.cancellationTokenSource.Cancel();
// TODO: await until DoLongProcessingAsync is finished
}
}
如何等待 LongProcessing 完成?
加法
有人说我应该等待任务。但是很可惜,Task 是 ButtonStart_Clicked 中的一个局部变量。我不确定是否应该将其作为类内的字段。
直到现在我还没有计划它,但只要它是一个局部变量,我可以通过单击几次来启动多个任务,并通过取消 CancellationTokenSource 将它们全部取消。
或者这真的是禁忌吗?
【问题讨论】:
-
如果你想知道任务何时完成,那么你
await它,就像你在其他想知道操作何时完成的方法中所做的那样。 -
await它并将其包装到一个 try-catch 中,如果等待的方法在内部调用传递的令牌上的ThrowIfCancellationRequested方法,您预计会出现OperationCanceledException。 -
我认为这可能很有趣:stackoverflow.com/questions/16656523/….
-
Related: .NET Async in shutdown methods? 如果你能确保取消会立即发生,那就简单多了,这样你就可以
Wait同步挂起的任务而不是awaiting它。跨度> -
取消会在一秒左右结束,所以取消不会有问题。我想我必须让我的任务成为一个字段,并确保只有一个任务在运行。感觉很尴尬,任务仍然存在,即使它完成了。
标签: c# async-await cancellationtokensource