【发布时间】:2021-12-14 23:27:31
【问题描述】:
我有一个正在执行无限循环的任务。
我有一个 CancellationToken,我将它传递给 Task.Run 调用,作为实际的 ExecutePoll 函数。
我等待几秒钟然后取消令牌。
当任务被取消时,应该运行一个 Continuation。
事实证明,只有当我明确调用 cancellationToken.ThrowIfCancellationRequested(); 时才会运行此延续。如果我只跳出循环,则任务始终处于以下状态:RanToCompletion
任何人都可以分享一下我在这里做错了什么吗?
代码:
using System.Threading;
using System.Threading.Tasks;
namespace TaskCancellationTest
{
class Program
{
private static CancellationTokenSource _pollProcessTokenSource;
static async Task Main(string[] args)
{
InitPollingProcess();
await Task.Delay(5000);
Console.WriteLine("Cancelling loop");
_pollProcessTokenSource.Cancel();
Console.WriteLine("Loop cancelled");
Console.ReadLine();
}
private static void InitPollingProcess()
{
try
{
_pollProcessTokenSource = new CancellationTokenSource();
Task pollForListenerConfigs = Task.Run(async () =>
{
await ExecutePoll(_pollProcessTokenSource.Token);
},
_pollProcessTokenSource.Token);
pollForListenerConfigs.ContinueWith(_ =>
{
Console.WriteLine("Poll process stopped!");
}, TaskContinuationOptions.OnlyOnCanceled);
pollForListenerConfigs.ContinueWith(t =>
{
Console.WriteLine($"Task status: {t.Status}");
});
}
catch (Exception ex)
{
Console.WriteLine($"Poll process failed with Exception:\n {ex.Message}");
}
}
private static async Task ExecutePoll(CancellationToken cancellationToken)
{
while (true)
{
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("Exit from poll loop!");
//cancellationToken.ThrowIfCancellationRequested(); // UNCOMMENT TO MAKE CONTINUATION RUN
break;
}
Console.WriteLine("Looping...");
await Task.Delay(1000);
}
}
}
}
【问题讨论】:
-
仅供参考,将取消令牌传递给
Task.Run仅在启动时检查取消令牌,如果已经取消,则立即返回取消的任务。否则,取消任务的唯一方法是在完成之前输入代码。此外,将异步调用放入Task.Run也没有多大意义,除非它恰好包含一些 CPU 绑定代码。
标签: c# .net-core async-await task-parallel-library