3
.NET中的TPL新手。試圖瞭解CancellationToken
以及它們如何通知取消正在執行的任務。下面的代碼只傳遞一個被取消的任務,因爲相同的令牌傳遞給兩個任務。我的假設是如果超時發生在第一個任務上並且它執行ctx.Cancel()
我需要一些幫助來理解爲什麼我只看到一個例外,因爲這兩個任務都應該被取消。我錯過了什麼,以及如何確保這兩個任務都取消並且不佔用內存資源。CancellationToken不取消所有任務
static void Main(string[] args)
{
Console.WriteLine("Starting application");
var ctx = new CancellationTokenSource();
var token = ctx.Token;
try
{
var task1 = new Program().Run("task1", token);
var task2 = new Program().Run("task2", token);
if (!task1.Wait(1000))
ctx.Cancel();
task2.Wait();
}
catch (AggregateException ex)
{
Console.WriteLine("Aggregate Exception occurred");
foreach (var e in ex.InnerExceptions)
{
Console.WriteLine(e.Message);
}
}
catch (Exception e)
{
Console.WriteLine($"Main Exception: {e.Message}");
}
finally
{
Console.WriteLine("Finish Application");
ctx.Dispose();
}
}
private async Task Run(string name, CancellationToken token)
{
while(true)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Task Cancelled");
token.ThrowIfCancellationRequested();
}
Console.WriteLine($"Executing {name} ...");
await Task.Delay(250, token);
}
}
只拋出一個異常,其他任務發生了什麼?另外,Console.WriteLine("Task Cancelled")
從未得到執行。
輸出:
Starting application
Executing task1 ...
Executing task2 ...
Executing task2 ...
Executing task1 ...
Executing task1 ...
Executing task2 ...
Executing task2 ...
Executing task1 ...
Aggregate Exception occurred
A task was canceled.
Finish Application
如果您沒有將CancellationToken傳遞給Task.Delay,那麼您有點錯過了取消CancellationToken。 –
@JoeWhite,我想你有一點,建議是爲了確保使用取消處理邏輯。 – mrtig
@mrtig這很有幫助,但這是否意味着一旦發佈取消令牌,所有任務都會被正確終止? –