[英]C# await Task.Run is not awaited
我有一些长期运行的后台计算任务
private async void StartButton_onClick(object sender, RoutedEventArgs e)
{
cts = new CancellationTokenSource();
var task = Task.Run(() => Calculate(cts.Token));
tasks.Add(task);
await task;
tasks.Remove(task);
cts = null;
}
当用户单击“ Cancel
按钮时,该任务可以被取消;当用户调用其他活动时,该任务应该被自动取消,例如,按“ Change
按钮以打开一个对话框来更改计算参数。
为了避免两次为两次写入取消代码,我将其移至单独的方法
public async void CancelAsync()
{
if (cts != null && !cts.IsCancellationRequested)
{
cts.Cancel();
await Task.WhenAll(tasks);
}
}
并从按钮click事件中调用它
private async void CancelButton_onClick(object sender, RoutedEventArgs e)
{
await Task.Run(() => CancelAsync());
}
private async void ChangeButton_onClick(object sender, RoutedEventArgs e)
{
await Task.Run(() => CancelAsync());
OpenDialog();
}
问题在于, 在 CancelAsync()
运行到CancelAsync()
之前 ,将调用OpenDialog()
方法。
请问我在这里错了什么?
由于您是从既未异步也未等待的lambda调用CancelAsync()的,因此该lambda将在CancelAsync()
方法返回之前完成。 为了使其按预期工作,请使用
public async Task CancelAsync()
{
if (cts != null && !cts.IsCancellationRequested)
{
cts.Cancel();
await Task.WhenAll(tasks);
}
}
await CancelAsync();
问题是使用Task.Run
,它旨在在线程池上运行一些同步代码,并让您等待其结果。 但是,您将异步代码传递给Task.Run
,就好像它是同步代码一样,因此Task.Run认为工作是在CancelAsync()返回任务时完成的,而不是在完成任务时完成的。
尝试以下方法:
private async void ChangeButton_onClick(object sender, RoutedEventArgs e)
{
await CancelAsync();
OpenDialog();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.