c# - 如何安全地取消任务?

标签 c# .net asynchronous async-await task

所以我有这个任务,点击一个按钮就开始了,我想知道如何安全地取消这个任务的循环?

private async Task RunAsync()
{
    PerformanceCounter counter = new PerformanceCounter("Process", "% Processor Time", pServer.ProcessName, true);
    Random r = new Random();
    while (true)
    {
        float pct = counter.NextValue() / 10f;
        ServerCPU = pct.ToString("0.0");
        await Task.Delay(2000);
    }
}

点击开始任务循环的按钮后,如何取消?

最佳答案

与处理 Thread 不同,您不能在没有合作的情况下取消/中止 Task。这就是 CancellationTokenCancellationTokenSource 发挥作用的地方。

您应该将 CancellationToken 传递到 RunAsync 并检查是否明确请求了取消(如果有意义)。在您的示例中,我可能会在每次迭代中都这样做:

private async Task RunAsync(CancellationToken ct)
{
    PerformanceCounter counter = new PerformanceCounter("Process", "% Processor Time", pServer.ProcessName, true);
    Random r = new Random();
    while (true)
    {
        ct.ThrowIfCancellationRequested();

        float pct = counter.NextValue() / 10f;
        ServerCPU = pct.ToString("0.0");
        await Task.Delay(2000, ct);
    }
}

在调用方站点上,您应该使用 CancellationTokenSource。它会给你一个 Token 传递给 RunAsync 以及触发取消的方法:

var cts = new CancellationTokenSource();
RunAsync(cts.Token);

// when you want to cancel it the task:
cts.Cancel();

您可以在 Cancellation in Managed Threads 中阅读有关该模式的更多信息.

关于c# - 如何安全地取消任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50672548/

相关文章:

C# 在这种情况下使用 "this"关键字?

javascript - npm 异步模块的替代品?

mysql - NodeJs 将多个请求的 Json 存储到 MySQL DB

javascript - nodejs 将相同的参数异步到函数数组?

c# - 如何在单个 NuGet 包中发送多个 `dotnet new` 模板?

c# - 请批评我的课

c# - 一种在不存储 key 的情况下将 key 存储在字典中的方法?

javascript - .NET 的 Enumerable.Select 是否有对应的 javascript/jQuery?

c# - 尝试将 Dictionary<string, object> 分配给字符串变量时出现错误

.net - EF在父删除时将外键设置为空