[英]c# async task cancellation
我在掌握任務和取消令牌方面遇到一些問題。 我制作了一個程序,如下所示:
static void Main(string[] args)
{
CancellationTokenSource token = new CancellationTokenSource();
Stopwatch stop = new Stopwatch();
stop.Start();
for (int i = 0; i < 5; i++)
{
//Thread.Sleep(1000);
Task.Factory.StartNew(() => myLongTask(token.Token, (i + 1) * 1000));
}
while (true)
{
Thread.SpinWait(1000);
if (stop.ElapsedMilliseconds > 3000)
{
token.Cancel();
}
}
}
public static void myLongTask(CancellationToken token, int time)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancelled");
return;
}
var sw = Stopwatch.StartNew();
Console.WriteLine($"Task {time / 1000} started");
while (sw.ElapsedMilliseconds < time)
Thread.SpinWait(1000);
Console.WriteLine($"Task {time / 1000} ended");
}
我同時運行5個任務(盡管當我不包括Thread.Sleep()
, for
循環似乎在任務開始之前就已經運行了?)。 當我運行程序時,所有任務都不會被取消。 另外困擾我的是...我在調用token.Cancel()
時實際上取消了什么任務? 如何選擇要殺死的5個任務中的哪一個? 我可以通過任務的變量來定義每個任務,但是由於它是由CancellationToken
觸發的,因此無法訪問其CancellationRequested
屬性。 那我需要5個不同的令牌嗎?
當我運行程序時,所有任務都不會被取消。
那是因為您只在任務開始時檢查取消令牌。 一旦超過了第一個令牌token.IsCancellationRequested
檢查,取消令牌將無濟於事。 如果將支票移入循環,如下所示:
while (sw.ElapsedMilliseconds < time)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancelled");
return;
}
Thread.SpinWait(1000);
}
...然后您將看到任務做出適當的反應。
另外困擾我的是...我在調用
token.Cancel()
時實際上取消了什么任務?
您不是要取消任務,而是要取消取消令牌。 任何觀察到取消令牌的任務都將被取消(或完成,或采取任何行動),但是任務和令牌之間沒有直接關聯。
當我們談論“取消任務”時,我們的意思是“取消我們認為任務正在觀察的令牌”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.