使用CancellationTokenSource
。該來源是CancellationTokens
的工廠。您將此令牌傳遞給您希望能夠以簡潔的方式取消其處理的所有人。如果要取消所有具有CancellationToken
和CancellationTokenSource
的進程,只需告知CancellationTokenSource
將取消發送到它生成的所有CancellationTokens
,從而取消所有具有來自此源令牌的進程。
而好的是,CancellationTokenSource
有一個CancelAfter(some timeout)
。
它的良好實踐,讓您的流程啓動器爲您提供cancellationToken,因此您的流程啓動器可以決定在一次調用中要取消哪些流程。
public async Task<MyResult> MyProcessAsync(CancellationToken cancellationToken, ...)
{
// do something lengthy processing, without await, regularly check if Cancellation requested
while (stillProcessing)
{
cancellationToken.ThrowIfCancellationRequested();
... // process
}
// do some processing with async-await:
await myDbContext.SaveChangesAsync(cancellationToken);
}
用法:
private async Task LengthyProcessing(...)
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
tokenSource.CancelAfter(TimeSpan.FromSeconds(5));
CancellationToken myCancellationToken = tokenSource.Token
try
{
// Start one task, don't await yet:
var myTask = await MyProcessAsync(myCancellationToken, ...)
// during processing there will be regular check if cancellation requested
// meanwhile, whenever myTask has to await, I can do some processing
// I'll have to check for cancellation regularly also:
while(...)
{
myCancellationToken.ThrowIfCancellationRequested();
DoSomeProcessing();
...
}
MyResult result = await myTask;
// if here, not cancelled. can use Result:
ProcessResult(result);
}
catch (OperationCanceledException exc)
{
ProcessOperationCanceled();
}
}
請注意,只有一個CancelltionTokenSource使用。無論何時此源認爲某些內容應該被取消,所有來自該源的令牌都會收到有關取消請求的通知。
而不是通過CancellationToken.ThrowIfCancellationRequested()
使用異常處理考慮使用bool CancellationToken.IsCancellationRequested
。
MSDN how to cancel a task and its children
請永遠不調用'Thread.Abort的()'除非你試圖強行碰撞出你的應用程序中。調用中止可能會破壞.NET運行時的狀態,導致**所有其他線程**的結果不可靠。 – Enigmativity