CancellationTokenSource
协作式取消 异步操作或长时间运行的同步操作。可以实现线程或任务的取消。
Register
当异步方法不能传递CancellationToken时,可以用CancellationToken注册委托异步方法相关的取消异步方法。
比如WebClient的DownloadFileAsync,要实现手动取消下载操作,可如下操作:
readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
using (WebClient client = new WebClient())
{
var token = _cancellationTokenSource.Token;
token.Register(() => client.CancelAsync());
// url等参数设置
client.Proxy = null;
client.DownloadFileAsync(new Uri(url), fileName);
client.DownloadProgressChanged += Client_DownloadProgressChanged;
client.DownloadFileCompleted += Client_DownloadFileCompleted;
}
// 当需要手动取消时
_cancellationTokenSource.Cancel();
Cancel
取消操作和Token注册的回调最好不要抛出异常。
任务取消后如果想重开任务,不能使用已经取消的token,需要重新声明一个对象。
多个任务协同时,最好每个任务都Token传参,并在任务中判断,是否取消操作。
try
{
// cts判断
if (_cts == null || _cts.IsCancellationRequested)
{
return null;
}
// token判断
token.ThrowIfCancellationRequested();
// TODO
}
catch (TaskCanceledException)
{
// Nothing
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Dispose
// 自动释放
using (var cts = new CancellationTokenSource())
{
// TODO
}
// 手动释放
private void DisponseCts(CancellationTokenSource cts)
{
if (cts != null)
{
if (!cts.IsCancellationRequested)
{
cts.Cancel();
}
cts.Dispose();
cts = null;
}
}