1、从 .NET Framework 4 开始,.NET Framework 在协作取消异步操作或长时间运行的同步操作时使用统一的模型。 此模型基于被称为取消标记(CancellationTokenSource)的轻量对象。 调用一个或多个可取消操作的对象(例如通过创建新线程(Thread)或任务(Task))将标记传递给每个操作。
2、用于实现协作取消模型的常规模式是:
-
实例化 CancellationTokenSource 对象,此对象管理取消通知并将其发送给单个取消标记。
-
将 CancellationTokenSource.Token 属性返回的标记传递给每个侦听取消的任务或线程。
-
为每个任务或线程提供响应取消的机制。
-
调用 CancellationTokenSource.Cancel 方法以提供取消通知。
3、在以下示例中,请求对象创建 CancellationTokenSource 对象,然后传递其 Token 属性到可取消操作中。 接收请求的操作通过轮询监视标记的 IsCancellationRequested 属性的值。 值变为 true
后,侦听器可以适当方式终止操作。 在此示例中,方法只需退出,很多情况下都只需执行此操作。
using System; using System.Threading; public class Example { public static void Main() { // 创建取消对象实例. CancellationTokenSource cts = new CancellationTokenSource(); // 传递token到取消操作. ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomeWork), cts.Token); Thread.Sleep(2500); // 发送取消操作 cts.Cancel(); Console.WriteLine("Cancellation set in token source..."); Thread.Sleep(2500); //取消对象最后要释放。 cts.Dispose(); } // Thread 2: The listener static void DoSomeWork(object obj) { CancellationToken token = (CancellationToken)obj; for (int i = 0; i < 100000; i++) { if (token.IsCancellationRequested) { Console.WriteLine("In iteration {0}, cancellation has been requested...", i + 1); // Perform cleanup if necessary. //... // Terminate the operation. break; } // Simulate some work. Thread.SpinWait(500000); } } } // The example displays output like the following: // Cancellation set in token source... // In iteration 1430, cancellation has been requested...
Note! 在标记的 IsCancellationRequested 属性设置为 true
后,不能重置为 false
。 因此,取消后不能重用取消标记。
4、 某些操作可能被阻止,导致其无法及时检查取消标记的值。 对于这些情况,可以注册在接收取消请求时取消阻止此方法的回调方法。
Register 方法返回专用于此目的的 CancellationTokenRegistration 对象。此方法可以注册一个取消请求发出后执行的一个操作。 以下示例演示了如何使用 Register 方法取消异步 Web 请求。
using System; using System.Net; using System.Threading; class Example { static void Main() { CancellationTokenSource cts = new CancellationTokenSource(); StartWebRequest(cts.Token); // cancellation will cause the web // request to be cancelled cts.Cancel(); } static void StartWebRequest(CancellationToken token) { WebClient wc = new WebClient(); wc.DownloadStringCompleted += (s, e) => Console.WriteLine("Request completed."); // Cancellation on the token will // call CancelAsync on the WebClient. token.Register(() => { wc.CancelAsync(); Console.WriteLine("Request cancelled!"); }); Console.WriteLine("Starting request."); wc.DownloadStringAsync(new Uri("http://www.contoso.com")); } }
5、在更复杂的情况下,用户委托可能需要通知库代码已发生取消。 在这种情况下,终止操作的正确方式是委托调用ThrowIfCancellationRequested 方法,这将引发 OperationCanceledException。 库代码可以在用户委托线程上捕获此异常,并检查异常的标记以确定异常是否表示协作取消或一些其他的异常情况。
using System; using System.Threading; using System.Threading.Tasks; class Program { static void Main() { var tokenSource2 = new CancellationTokenSource(); CancellationToken ct = tokenSource2.Token; var task = Task.Factory.StartNew(() => { // Were we already canceled? ct.ThrowIfCancellationRequested(); bool moreToDo = true; while (moreToDo) { // Poll on this property if you have to do // other cleanup before throwing. if (ct.IsCancellationRequested) { // Clean up here, then... ct.ThrowIfCancellationRequested(); } } }, tokenSource2.Token); // Pass same token to StartNew. tokenSource2.Cancel(); // Just continue on this thread, or Wait/WaitAll with try-catch: try { task.Wait(); } catch (AggregateException e) { foreach (var v in e.InnerExceptions) Console.WriteLine(e.Message + " " + v.Message); } finally { tokenSource2.Dispose(); } Console.ReadKey(); } }
相关推荐
使用CancellationTokenSource和CancellationToken的任务取消和任务中止 应用于任务的观察者设计模式。 它可以扩展以监视问题。 事件处理程序。 IDisposable模式。 提供了带有NUnit3的NUnit。 预先增强功能,可将...
.net让线程支持超时 使用 CancellationTokenSource 代码如下:private static ... var thread = new Thread(() => { Console.WriteLine(String.Format(“线程{0}执行中”, Thread.CurrentThread.ManagedThreadId));
重要威士忌 外部模块集合。 请注意,此存储库中的所有模块都是实验性的,可以删除。 模组 名称 描述 评论 添加界面以选择特殊映射 最小命令参数库 具有中间件支持的事件发射...Async.CancellationTokenSource Ca
此外,该库包含简单的DataFlow,无线程参与者(代理),Task类的功能组合器,有用的异步原语(AsyncSemaphore,AsyncProducerConsumerCollection,CancellationToken,CancellationTokenSource,AsyncMutex,...
CancellationTokenSource tokenSource = new CancellationTokenSource (); string batchID = " -1 " ; using ( var httpClient = new HttpClient ()) { httpClient . DefaultRequestHeaders . Add (" wolfram - ...
await job.RunContinuousAsync(cancellationToken: new CancellationTokenSource(TimeSpan.FromMilliseconds(10)).Token); // job.RunCount > 10;2、Queue Processor Jobs:和上面的Jobs差不多,只是这个是...
可怕的订阅者 这是一个简单的库,能够搜索,获取和解析的xdcc装箱单由Daniel Belz用:red_heart:︎建造入门获取所有机器人private static async Task Main (){ var httpClient = new HttpClient (); var fetcher = ...
天气搜索 我编写了此Blazor应用程序以... 使用DataAnnotations验证模型使用CancellationTokenSource超时需要花费太长时间的Web请求。意见建议如果要使用WeatherAPI NuGet软件包以及最新的API,则可能要在WeatherAPI帐