c# - 检查 CancellationToken 是否已被取消
问题描述
我创建了一个小演示项目来帮助我了解如何使用取消令牌。我了解您取消了令牌并检查是否已请求取消,但是有没有办法可以检查取消是否已实现?在下面的示例中,我不想在 DoWork() 完成运行之前再次运行 Work()。
public class Program
{
public static CancellationTokenSource tokenSource;
private static void Main(string[] args)
{
while (true)
{
Work();
}
}
public static async void Work()
{
tokenSource = new CancellationTokenSource();
Console.WriteLine("Press any key to START doing work");
Console.ReadLine();
Console.WriteLine("Press any key to STOP doing work");
DoWork(tokenSource.Token);
Console.ReadLine();
Console.WriteLine("Stopping...");
tokenSource.Cancel();
}
public static async void DoWork(CancellationToken cancelToken)
{
while (true)
{
Console.WriteLine("Working...");
await Task.Run(() =>
{
Thread.Sleep(1500);
});
if (cancelToken.IsCancellationRequested)
{
Console.WriteLine("Work Cancelled!");
return;
}
}
}
}
解决方案
您通常不想制作您的DoWork
功能async void
-async Task
而是制作它。这样您就可以看到它何时完成(或被取消)。
您可能还想使用cancelToken.ThrowIfCancellationRequested()
. 这会抛出一个OperationCanceledException
,你可以抓住它。
public class Program
{
public static CancellationTokenSource tokenSource;
private static async Task Main(string[] args)
{
while (true)
{
await Work();
}
}
public static async Task Work()
{
tokenSource = new CancellationTokenSource();
Console.WriteLine("Press any key to START doing work");
Console.ReadLine();
Console.WriteLine("Press any key to STOP doing work");
var task = DoWork(tokenSource.Token);
Console.ReadLine();
Console.WriteLine("Stopping...");
tokenSource.Cancel();
try
{
await task;
}
catch (OperationCanceledException)
{
// Task was cancelled
}
}
public static async Task DoWork(CancellationToken cancelToken)
{
while (true)
{
Console.WriteLine("Working...");
await Task.Run(() =>
{
Thread.Sleep(1500);
});
cancelToken.ThrowIfCancellationRequested();
}
}
}
此代码依赖于 C# 7 中引入的“async main”。如果您没有这个,您可以将 Main 方法编写为:
private static void Main(string[] args)
{
while (true)
{
Work().Wait();
}
}
推荐阅读
- python - 尝试访问 Django Admin 文档不会引发反向匹配错误
- python-3.x - 无法使用 xport 将 xport 文件读入 python
- docker - 无法在 docker 映像中安装 Jmeter 插件管理器
- laravel - 在 laravel 中创建 db:seed 作为整数时出错
- javascript - 为什么这个简单的应用程序会抛出这个错误?
- mongodb - 在 MongoDB 中,我可以在不关闭每个实例的情况下运行 compact 命令吗?
- wordpress - WordPress 自动登录表单填写按钮
- webpack - 从 v4 替换 Webpack v5 中进程的 polyfill
- javascript - 这两种发布方法 [Typescript] 之间有什么区别吗?
- flutter - Flutter Web:CORS 策略已阻止在 ** 从源 ** 访问 XMLHttpRequest