首页 > 解决方案 > C# await Task.Run 不等待

问题描述

我有一些长期运行的后台计算任务

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);
    }
}

并从按钮单击事件中调用它

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();
}

问题是该OpenDialog()方法在运行完成之前被调用。 CancelAsync()

请问我这里有什么问题吗?

标签: c#async-await

解决方案


由于您从非异步也非等待的 lambda 调用 CancelAsync(),因此 lambda 将在CancelAsync()方法返回之前完成。为了使其按预期用途工作

public async Task CancelAsync()
{
    if (cts != null && !cts.IsCancellationRequested)
    {
        cts.Cancel();
        await Task.WhenAll(tasks);
    }
}

await CancelAsync();

推荐阅读