.net4.0线程池取消执行的实际应用

2010年年初微软就正式发布了.net4.0VS2010,不久我们有B/S项目就开始用起来了,但对一些服务端特性和新技术并没用,比如.net4.0对线程池的一些优化。

.net4.0线程池新增了Cooperative Cancellation模式,它可以让线程池取消继续执行,在.net4.0以前,如果把任务交给了线程池,想要它停止下来几乎不可能,因为微软没有这样的接口,除非自己封装一个线程池,但.net框架自带的线程池执行会根据机器当前CPU、内存等综合资源来调度的,调用更方便,效果也更好。

2年前,我帮测试团队写了一个小工具,帮助他们拨测网站,以前他们会找几个测试人员每天把网站的每个链接都点一下,看是否有链接存在问题,可能有其他工具可以做到这点,但没找到简单的,最后我写了一个软件,配置好网站域名,就能自动去爬取几乎所有该网站的地址来检测是否可访问。软件运行中界面如下:

这里我用扫描移动官网来测试,其中取消按钮是我最近加的,为了实现线程池停止执行任务做的。其实这个软件中间修改了多次,比如添加预警功能,添加扫描深度配置,添加作为刷网站访问量的功能,现在添加取消执行扫描的功能,包括今天我运行,还看到不同路径识别可能还存在一些BUG需要修复。

 

.Net4.0System.Threading命名空间下增加了:CancellationTokenSource类和CancellationToten结构体,利用他们可以来取消线程池的执行。同时还增加了System.Threading.Tasks命名空间,它包括一个Task类和TaskFactory的工厂类,它可以达到和以前ThreadPool一样的功能,而且它可以在线程执行完毕后返回结果等功能。

软件中以前处理原理这里不做介绍了,直接说新增的功能,首先我在窗体类下定义了:

        static CancellationTokenSource source = new CancellationTokenSource();

        static CancellationToken token = source.Token;

然后把真正扫描网站是否有效的调用方法由以前直接线程池:

                    ThreadPool.QueueUserWorkItem((temp) => startAnalyzer(temp), transferHref);

替换为如下:

                    Task.Factory.StartNew((temp) => startAnalyzer(temp), transferHref, token);

这里的token即是上面定义的static变量的token

当我们点击窗体的取消按钮时,它的执行代码如下:

 

        private void btnCancel_Click(object sender, EventArgs e)

        {

            source.Cancel();

            source.Token.Register(() =>

            {

                this.OnAnalysisEnd();

            });

        }

首先调用sourceCancel()方法,达到停止线程池的功能,然后为source.Token注册了取消成功后回调事件。CancellationTokenSource类和CancellationToten结构体还有其他控制任务的方法,比如source.Token.WaitHandle.WaitOne()等,这里只是Cancel的一个应用。

多线程的精确控制会比较麻烦,微软对线程池的不断改进将更有助于我们对多线程的应用,由于我们项目多数是B/S,并且生产环境的多线程应用并不多,我也没很深入的研究,本篇文章抛砖引玉,希望以后有机会可以更灵活的应用多线程技术。

原文地址:https://www.cnblogs.com/Lawson/p/2115387.html