大多数情况下,我将CancellationTokenSource
用于超时目的。为了避免忘记dispose
,当我完成CancellationTokenSource
时,我使用的是using
语句。但是在using
语句结束之前,我总是在做CancellationTokenSource.Cancel()
。
如果未使用取消,是否有必要在处置前取消CancellationTokenSource
吗?
这是我正在执行此操作的代码示例。
using (CancellationTokenSource TokenSource = new CancellationTokenSource(nTimeout * 1000))
{
for (int i = 0; i < nLoop; i++)
{
if (TokenSource.Token.IsCancellationRequested)
{
bSuccess = false;
break;
}
await Task.Delay(cDelay);
// do some work
}
TokenSource.Cancel();
}
最佳答案
处置CancellationTokenSource
后,基于此来源的令牌可能会抛出ObjectDisposedException
,因此在处置该来源之后,请勿使用CancellationTokenSource.Token
。幸运的是,我没有在您的代码中看到这种情况。
取消CancellationTokenSource
时,它会更改状态并通知已为令牌注册的回调。但是,当您的代码将要处置CancellationTokenSource
时,您已经使用令牌完成了操作,无需取消它。
因此,根据您的情况,无需在处置前取消CancellationTokenSource
。但是,您的用例有些特殊。当您有后台任务时,您应该等待任务完成,然后再处理源(如我的第一段所述):
using (var cts = new CancellationTokenSource()) {
var task = Task.Run(() => DoSomething(cts.Token));
// Cancel cts or let it cancel itself based on a timeout.
// Then wait for the task to end.
await task;
}