查看本系列其他文章,请参看
为丛台等地区用户提供了全套网页设计制作服务,及丛台网站建设行业解决方案。主营业务为网站设计、成都网站建设、丛台网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
[[11687]]
因为Task是.NET 4并行编程最为核心的一个类,也我们在是在并行编程常常打交道的类,所以,对Task对全面的了解很有必要。
上篇文章主要讲述了如何创建一个task,本篇文章主要讲述如何取消一个task。
本篇主的主要议题如下:
1. 通过轮询的方式检测Task是否被取消
2. 用委托delegate来检测Task是否被取消
3. 用Wait Handle还检测Task是否被取消
4. 取消多个Task
5. 创建组合的取消Task的Token
6. 判断一个Task是否已经被取消了
本篇的理论不多,代码的例子很多。
在TPL中一个标准化的操作就是”取消Task”。之所以说它是个标准化的操作,其实是把这个操作和之前传统的多线程编程进行比较而言的。
在之前的多线程编程中,我们一般是自己写一些代码来取消线程的运行。但是在.NET 4的TPL中就内置了取消的方法,可能我们觉得TPL没有必要内置这些代码,因为太简单了。但是这个内置的方法不仅仅只是取消了运行的Task,而且还减小了在取消运行的Task时可能产生的一些风险,我们后续文章会详细讲述。
创建一个取消的Task一般要进行下面一些步骤:
a.创建System.Threading.CancellationTokenSource的一个实例:
// create the cancellation token source ancellationTokenSource tokenSource = new CancellationTokenSource();
b.通过CancellationTokenSource.Token属性获得一个System.Threading.CancellationToken:
CancellationToken token = tokenSource.Token;
c.创建一个新的Task或者Task,并且在构造函数传入Action或者Action的委托作为***个参数,传入CancellationToken作为第二个参数: Task task = new Task(new Action(printMessage), token); d.调用Task的Start()方法。上面的步骤和我们之前介绍的创建一个Task的代码几乎一样,只是在构造函数中多传入了一个参数。如果想要取消一个Task的运行,只要调用CancellationToken实例的Cancel()方法就可以了。有点要特别注意的,当我们调用了Cancel()方法之后,.NET Framework不会强制性的去关闭运行的Task。我们自己必须去检测之前在创建Task时候传入的那个CancellationToken。我们在创建Task是传入CancellationToken到构造函数,其实这个CancellationToken就是.NET Framework用来避免我们再次运行已经被取消的Task,可以说就是一个标志位。首先,进入***个议题:1.通过轮询的方式检测Task是否被取消在很多Task内部都包含了循环,用来处理数据。我们可以在循环中通过CancellationToken的IsCancellationRequest属性来检测task是否被取消了。如果这个属性为true,那么我们就得跳出循环,并且释放task所占用的资源(如数据库资源,文件资源等).我们也可以在task运行体中抛出System.Threading.OperationCanceledException来取消运行的task。代码如下:代码 while (true) { if (token.IsCancellationRequested) { // tidy up and release resources throw new OperationCanceledException(token); } else { // do a unit of work } } 如果我们没有任何的资源要释放,那么只要简单的调用CancellationToken.ThrowIfCancellationRequested()方法,这个方法会检查是否要取消task,并且抛出异常。代码如下: while (true) token.ThrowIfCancellationRequested(); // do a unit of work } 下面就给出有一个完整的例子:创建一个可以取消的task,并且通过轮询不断的检查是否要取消task代码如下:代码 static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the task Task task = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancel detected"); throw new OperationCanceledException(token); } else { Console.WriteLine("Int value {0}", i); } } }, token); // wait for input before we start the task Console.WriteLine("Press enter to start task"); Console.WriteLine("Press enter again to cancel task"); Console.ReadLine(); // start the task task.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling task"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } 2. 用委托delegate来检测Task是否被取消我们可以在注册一个委托到CancellationToken中,这个委托的方法在CancellationToken.Cancel()调用之前被调用。我们可以用这个委托中的方法来作为一个检测task是否被取消的另外一个可选的方法,因为这个方法是在Cancel()方法被调用之前就调用的,所以这个委托中的方法可以检测task是否被cancel了,也就是说,只要这个委托的方法被调用,那么就说这个CancellationToken.Cancel()方法被调用了,而且在这个委托的方法中我们可以做很多的事情,如通知用户取消操作发生了。下面的代码给出了一个例子。代码 static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the task Task task = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancel detected"); throw new OperationCanceledException(token); } else { Console.WriteLine("Int value {0}", i); } } }, token); // register a cancellation delegate token.Register(() => { Console.WriteLine(">>>>>> Delegate Invoked\n"); }); // wait for input before we start the task Console.WriteLine("Press enter to start task"); Console.WriteLine("Press enter again to cancel task"); Console.ReadLine(); // start the task task.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling task"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } 3. 用Wait Handle还检测Task是否被取消第三种方法检测task是否被cancel就是调用CancellationToken.WaitHandle属性。对于这个属性的详细使用,在后续的文章中会深入的讲述,在这里主要知道一点就行了:CancellationToken的WaitOne()方法会阻止task的运行,只有CancellationToken的cancel()方法被调用后,这种阻止才会释放。在下面的例子中,创建了两个task,其中task2调用了WaitOne()方法,所以task2一直不会运行,除非调用了CancellationToken的Cancel()方法,所以WaitOne()方法也算是检测task是否被cancel的一种方法了。代码 static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the task Task task1 = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancel detected"); throw new OperationCanceledException(token); } else { Console.WriteLine("Int value {0}", i); } } }, token); // create a second task that will use the wait handle Task task2 = new Task(() => { // wait on the handle token.WaitHandle.WaitOne(); // write out a message Console.WriteLine(">>>>> Wait handle released"); }); // wait for input before we start the task Console.WriteLine("Press enter to start task"); Console.WriteLine("Press enter again to cancel task"); Console.ReadLine(); // start the tasks task1.Start(); task2.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling task"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } 4. 取消多个Task我们可以使用一个CancellationToken来创建多个不同的Tasks,当这个CancellationToken的Cancel()方法调用的时候,使用了这个token的多个task都会被取消。代码 static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the tasks Task task1 = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { token.ThrowIfCancellationRequested(); Console.WriteLine("Task 1 - Int value {0}", i); } }, token); Task task2 = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { token.ThrowIfCancellationRequested(); Console.WriteLine("Task 2 - Int value {0}", i); } }, token); // wait for input before we start the tasks Console.WriteLine("Press enter to start tasks"); Console.WriteLine("Press enter again to cancel tasks"); Console.ReadLine(); // start the tasks task1.Start(); task2.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling tasks"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } 5. 创建组合的取消Task的Token我们可以用CancellationTokenSource.CreateLinkedTokenSource()方法来创建一个组合的token,这个组合的token有很多的CancellationToken组成。主要组合token中的任意一个token调用了Cancel()方法,那么使用这个组合token的所有task就会被取消。代码如下:代码 static void Main(string[] args) { // create the cancellation token sources CancellationTokenSource tokenSource1 = new CancellationTokenSource(); CancellationTokenSource tokenSource2 = new CancellationTokenSource(); CancellationTokenSource tokenSource3 = new CancellationTokenSource(); // create a composite token source using multiple tokens CancellationTokenSource compositeSource = CancellationTokenSource.CreateLinkedTokenSource( tokenSource1.Token, tokenSource2.Token, tokenSource3.Token); // create a cancellable task using the composite token Task task = new Task(() => { // wait until the token has been cancelled compositeSource.Token.WaitHandle.WaitOne(); // throw a cancellation exception throw new OperationCanceledException(compositeSource.Token); }, compositeSource.Token); // start the task task.Start(); // cancel one of the original tokens tokenSource2.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } 6. 判断一个Task是否已经被取消了可以使用Task的IsCancelled属性来判断task是否被取消了。代码如下:代码 static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource1 = new CancellationTokenSource(); // create the cancellation token CancellationToken token1 = tokenSource1.Token; // create the first task, which we will let run fully Task task1 = new Task(() => { for (int i = 0; i < 10; i++) { token1.ThrowIfCancellationRequested(); Console.WriteLine("Task 1 - Int value {0}", i); } }, token1); // create the second cancellation token source CancellationTokenSource tokenSource2 = new CancellationTokenSource(); // create the cancellation token CancellationToken token2 = tokenSource2.Token; // create the second task, which we will cancel Task task2 = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { token2.ThrowIfCancellationRequested(); Console.WriteLine("Task 2 - Int value {0}", i); } }, token2); // start all of the tasks task1.Start(); task2.Start(); // cancel the second token source tokenSource2.Cancel(); // write out the cancellation detail of each task Console.WriteLine("Task 1 cancelled? {0}", task1.IsCanceled); Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); } 分享文章:.NET 4并行编程入门之Task的取消 文章源于:http://www.shufengxianlan.com/qtweb/news13/532163.html 网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等 广告 声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联 猜你还喜欢下面的内容 人大金仓同时揽获软交会两项大奖 企业云:明确需求更合适 怎么使用香港服务器才安全 SSL入门:SSL支持服务器认证 xcode可以在windows下运行吗?(xcodewindows能用) sql触发器不执行怎么解决 PHPpreg_quote():对正则表达式进行转义 怎么做耳机?(怎么做耳机壳) 解决Redis中线程安全问题之道(redis线程安全问题) 手机网站建设知识 网站空间已经到期暂停是什么意思?(网站空间过期被释放怎么办) jenkns什么意思 怎么禁用软件 Java类加载机制及类加载器详解 搭建Redis哨兵实现集群高可用(搭建redis哨兵) 美国站群服务器的优点有哪些 赢杰历史原型 利用Redis查看实时日志(redis查看实时日志) 代码签名是为了什么EV代码签名证书有哪些功能(ev代码签名购买) InheritableThreadLocal异步传递数据实现原理 手机如何访问电脑html文件夹 别再误解了对公有云安全的三大误区 怎样查看网站域名服务商?查询域名服务商 开发者眼中的Moblin和Android 域名永不丢失解决方法?(丢弃找回域名-其他问题) 同城分类信息 搅拌罐车 酒店设计 除甲醛 展览展示 纸箱 石雕 砂岩浮雕 LED显示屏 iso认证 塑料袋 茶楼设计 广告设计 不锈钢雕塑 假山制作 凿毛机 玻璃贴膜 成都网站建设 成都水电改造 成都温江机房 网站SEO优化 攀枝花网站建设 成都铺面装修 边坡防护网 手机网站制作设计 中建建业环保 成都多线机房 申请域名 ssl数字证书 成都app软件开发 托管服务器 外贸网站建设方案 香港云主机 成都网站设计 宜宾网站建设 手机网站设计 手机网站制作
Task task = new Task(new Action(printMessage), token);
d.调用Task的Start()方法。
上面的步骤和我们之前介绍的创建一个Task的代码几乎一样,只是在构造函数中多传入了一个参数。
如果想要取消一个Task的运行,只要调用CancellationToken实例的Cancel()方法就可以了。
有点要特别注意的,当我们调用了Cancel()方法之后,.NET Framework不会强制性的去关闭运行的Task。
我们自己必须去检测之前在创建Task时候传入的那个CancellationToken。
我们在创建Task是传入CancellationToken到构造函数,其实这个CancellationToken就是.NET Framework用来避免我们再次运行已经被取消的Task,可以说就是一个标志位。
首先,进入***个议题:
1.通过轮询的方式检测Task是否被取消
在很多Task内部都包含了循环,用来处理数据。我们可以在循环中通过CancellationToken的IsCancellationRequest属性来检测task是否被取消了。如果这个属性为true,那么我们就得跳出循环,并且释放task所占用的资源(如数据库资源,文件资源等).
我们也可以在task运行体中抛出System.Threading.OperationCanceledException来取消运行的task。
代码如下:
代码
while (true) { if (token.IsCancellationRequested) { // tidy up and release resources throw new OperationCanceledException(token); } else { // do a unit of work } }
如果我们没有任何的资源要释放,那么只要简单的调用CancellationToken.ThrowIfCancellationRequested()方法,这个方法会检查是否要取消task,并且抛出异常。代码如下:
while (true) token.ThrowIfCancellationRequested(); // do a unit of work }
下面就给出有一个完整的例子:创建一个可以取消的task,并且通过轮询不断的检查是否要取消task
static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the task Task task = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancel detected"); throw new OperationCanceledException(token); } else { Console.WriteLine("Int value {0}", i); } } }, token); // wait for input before we start the task Console.WriteLine("Press enter to start task"); Console.WriteLine("Press enter again to cancel task"); Console.ReadLine(); // start the task task.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling task"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); }
我们可以在注册一个委托到CancellationToken中,这个委托的方法在CancellationToken.Cancel()调用之前被调用。
我们可以用这个委托中的方法来作为一个检测task是否被取消的另外一个可选的方法,因为这个方法是在Cancel()方法被调用之前就调用的,所以这个委托中的方法可以检测task是否被cancel了,也就是说,只要这个委托的方法被调用,那么就说这个CancellationToken.Cancel()方法被调用了,而且在这个委托的方法中我们可以做很多的事情,如通知用户取消操作发生了。
下面的代码给出了一个例子。
static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the task Task task = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancel detected"); throw new OperationCanceledException(token); } else { Console.WriteLine("Int value {0}", i); } } }, token); // register a cancellation delegate token.Register(() => { Console.WriteLine(">>>>>> Delegate Invoked\n"); }); // wait for input before we start the task Console.WriteLine("Press enter to start task"); Console.WriteLine("Press enter again to cancel task"); Console.ReadLine(); // start the task task.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling task"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); }
第三种方法检测task是否被cancel就是调用CancellationToken.WaitHandle属性。对于这个属性的详细使用,在后续的文章中会深入的讲述,在这里主要知道一点就行了:CancellationToken的WaitOne()方法会阻止task的运行,只有CancellationToken的cancel()方法被调用后,这种阻止才会释放。
在下面的例子中,创建了两个task,其中task2调用了WaitOne()方法,所以task2一直不会运行,除非调用了CancellationToken的Cancel()方法,所以WaitOne()方法也算是检测task是否被cancel的一种方法了。
static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the task Task task1 = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { if (token.IsCancellationRequested) { Console.WriteLine("Task cancel detected"); throw new OperationCanceledException(token); } else { Console.WriteLine("Int value {0}", i); } } }, token); // create a second task that will use the wait handle Task task2 = new Task(() => { // wait on the handle token.WaitHandle.WaitOne(); // write out a message Console.WriteLine(">>>>> Wait handle released"); }); // wait for input before we start the task Console.WriteLine("Press enter to start task"); Console.WriteLine("Press enter again to cancel task"); Console.ReadLine(); // start the tasks task1.Start(); task2.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling task"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); }
我们可以使用一个CancellationToken来创建多个不同的Tasks,当这个CancellationToken的Cancel()方法调用的时候,使用了这个token的多个task都会被取消。
static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token CancellationToken token = tokenSource.Token; // create the tasks Task task1 = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { token.ThrowIfCancellationRequested(); Console.WriteLine("Task 1 - Int value {0}", i); } }, token); Task task2 = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { token.ThrowIfCancellationRequested(); Console.WriteLine("Task 2 - Int value {0}", i); } }, token); // wait for input before we start the tasks Console.WriteLine("Press enter to start tasks"); Console.WriteLine("Press enter again to cancel tasks"); Console.ReadLine(); // start the tasks task1.Start(); task2.Start(); // read a line from the console. Console.ReadLine(); // cancel the task Console.WriteLine("Cancelling tasks"); tokenSource.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); }
我们可以用CancellationTokenSource.CreateLinkedTokenSource()方法来创建一个组合的token,这个组合的token有很多的CancellationToken组成。主要组合token中的任意一个token调用了Cancel()方法,那么使用这个组合token的所有task就会被取消。代码如下:
static void Main(string[] args) { // create the cancellation token sources CancellationTokenSource tokenSource1 = new CancellationTokenSource(); CancellationTokenSource tokenSource2 = new CancellationTokenSource(); CancellationTokenSource tokenSource3 = new CancellationTokenSource(); // create a composite token source using multiple tokens CancellationTokenSource compositeSource = CancellationTokenSource.CreateLinkedTokenSource( tokenSource1.Token, tokenSource2.Token, tokenSource3.Token); // create a cancellable task using the composite token Task task = new Task(() => { // wait until the token has been cancelled compositeSource.Token.WaitHandle.WaitOne(); // throw a cancellation exception throw new OperationCanceledException(compositeSource.Token); }, compositeSource.Token); // start the task task.Start(); // cancel one of the original tokens tokenSource2.Cancel(); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); }
可以使用Task的IsCancelled属性来判断task是否被取消了。代码如下:
static void Main(string[] args) { // create the cancellation token source CancellationTokenSource tokenSource1 = new CancellationTokenSource(); // create the cancellation token CancellationToken token1 = tokenSource1.Token; // create the first task, which we will let run fully Task task1 = new Task(() => { for (int i = 0; i < 10; i++) { token1.ThrowIfCancellationRequested(); Console.WriteLine("Task 1 - Int value {0}", i); } }, token1); // create the second cancellation token source CancellationTokenSource tokenSource2 = new CancellationTokenSource(); // create the cancellation token CancellationToken token2 = tokenSource2.Token; // create the second task, which we will cancel Task task2 = new Task(() => { for (int i = 0; i < int.MaxValue; i++) { token2.ThrowIfCancellationRequested(); Console.WriteLine("Task 2 - Int value {0}", i); } }, token2); // start all of the tasks task1.Start(); task2.Start(); // cancel the second token source tokenSource2.Cancel(); // write out the cancellation detail of each task Console.WriteLine("Task 1 cancelled? {0}", task1.IsCanceled); Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled); // wait for input before exiting Console.WriteLine("Main method complete. Press enter to finish."); Console.ReadLine(); }
分享文章:.NET 4并行编程入门之Task的取消 文章源于:http://www.shufengxianlan.com/qtweb/news13/532163.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
广告
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联
猜你还喜欢下面的内容
手机网站建设知识
同城分类信息