之前,我就开始关注Thread的知识。看过计算限制异步操作、I/O限制异步操作、Task、Parallel、APM、AsyncEnumerator…也做了相应的笔记。可是,具体Coding起来,还是会感到举步艰难。Why?复杂的知识让我复杂的想问题。上午,看了Jimmy Zhang的如何在30岁前年薪超过30万,说到“我发现越是真理,就越是趋于简单”。也许,最好的是简单的,关键在于,你愿不愿意,能不能这样去做。

这里,不讲Thread的基本知识了。就陆续举出几个不同方法实现的例子,比较下,会发现简明才是美。(以下例子中,没有充分考虑到performance hit,请指正!)

协作式取消 VS 线程终止

协作式取消的介绍在Thread基础-计算限制的异步操作(CLR)介绍过了,这里不再做重复。直接Coding。

这里我们需要创建一个应用程序并在一个新线程中生成素数。在这个应用程序中有停止生成素数线程的选项。(盗用下DanielWise兄的例子哈)

界面如下:

协作式实现:

/*************************************
/* Copyright (c) 2012 mumuZ
 * 
 * Author:mumuZ
 * Blog:o  http://www.cnblogs.com/lnetmor/
 * Email:o lnetmor@gmail.com
 * 
 */
 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
 
namespace ThreadIsSoEasy_MonDontCare_
{
    public partial class Form1 : Form
    {
        private Thread primeNumberThread;
        public delegate void UpdateData(string returnVal);
        public delegate void UpdateButtonControl(string id, string isEnabled);
        private CancellationTokenSource cancellationTokenSource;
 
        public Form1()
        {
            InitializeComponent();
 
            cmdStart.Enabled = true;
            cmdStop.Enabled = false;
        }
 
        private void cmdStart_Click(object sender, EventArgs e)
        {
            lstPrime.Items.Clear();
 
            cancellationTokenSource = new CancellationTokenSource();
            cmdStop.Enabled = true;
            cmdStart.Enabled = false;
            ThreadPool.QueueUserWorkItem(o => GeneratePrimeNumbers(cancellationTokenSource.Token));
        }
 
        private void cmdStop_Click(object sender, EventArgs e)
        {
            cancellationTokenSource.Cancel();
            cmdStop.Enabled = false;
            cmdStart.Enabled = true;
        }

GeneratePrimeNumbers方法需要传入一个CancellationToken实例。具体实现如下:

public void GeneratePrimeNumbers(CancellationToken token)
{
    long lngCounter = 2;
    long lngNumber = 3;
    long lngDivideByCounter;
    bool blnIsPrime;
    long[] PrimeArray = new long[256];
    string[] args = new string[] { "2" };
    UpdateData UIDel = new UpdateData(UpdateUI);
    UpdateButtonControl UIControl = new UpdateButtonControl(UpdateButtonState);
 
    //We know that the first prime is 2.
    //Therefore, let's add it to the list and start from 3.
    PrimeArray[1] = 2;
    //lstPrime.Items.Add(2);
    this.Invoke(UIDel, args);
 
    while (lngCounter < 256)
    {
        blnIsPrime = true;
 
        if (token.IsCancellationRequested)
        {
            args[0] = "Cancelled!";
            this.Invoke(UIDel, args);
            break;
        }
 
        //Try dividing this number by any already found prime
        //Which is smaller then the root of this number.
        for (lngDivideByCounter = 1; PrimeArray[lngDivideByCounter]
            * PrimeArray[lngDivideByCounter] <= lngNumber;
            lngDivideByCounter++)
        {
            if (lngNumber % PrimeArray[lngDivideByCounter] == 0)
            {
                //This is not a prime number
                blnIsPrime = false;
                //Exit the loop break;
            }
        }
 
        //If this is a prime number then display it
        if (blnIsPrime)
        {
            //Guess we found a new prime.
            PrimeArray[lngCounter] = lngNumber;
            //Increase prime found count.
            lngCounter++;
            //lstPrime.Items.Add(lngNumber);
            args[0] = lngNumber.ToString();
            this.Invoke(UIDel, args);
            //Sleep 100 milliseconds.
            //This will simulate the time lag and we'll get time
            //to pause and resume the thread.
            Thread.Sleep(100);
        }
        lngNumber += 2;
    }
    this.Invoke(UIControl, new string[] { "cmdStart", "true" });
    this.Invoke(UIControl, new string[] { "cmdStop", "false" });
}

细心地朋友应该注意到GeneratePrimeNumbers方法内,我是用两个委托来修改UI的,相信大家都知道其中的道理,不多说了。下面就来看下由线程终止来实现该功能。

/*************************************
/* Copyright (c) 2012 mumuZ
 * 
 * Author:mumuZ
 * Blog:o  http://www.cnblogs.com/lnetmor/
 * Email:o lnetmor@gmail.com
 * 
 */
 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
 
namespace ThreadIsSoEasy_MonDontCare_
{
    public partial class ThreadAbortForm : Form
    {
        private Thread primeNumberThread;
        public delegate void UpdateData(string returnVal);
        public delegate void UpdateButtonControl(string id, string isEnabled);
 
        public ThreadAbortForm()
        {
            InitializeComponent();
            cmdStart.Enabled = true;
            cmdStop.Enabled = false;
        }
 
        private void cmdStart_Click(object sender, EventArgs e)
        {
            lstPrime.Items.Clear();
            primeNumberThread = new Thread(new ThreadStart(GeneratePrimeNumbers));
            primeNumberThread.Start();
            cmdStart.Enabled = false;
            cmdStop.Enabled = true;
        }
 
        private void cmdStop_Click(object sender, EventArgs e)
        {
            primeNumberThread.Abort();
            lstPrime.Items.Add("Cancelled!");
            cmdStart.Enabled = true;
            cmdStop.Enabled = false;
        }

现在,GeneratePrimeNumbers方法不需要有CancellationToken了。即,内部逻辑就简略了很多。

以上两个例子孰差孰优,仁者见仁,智者见智吧。笔者还是新苗于后者,这样我的代码就可以少CancellationTokenSource 和CancellationToken两个类,并且生成素数方法GeneratePrimeNumbers的逻辑也简明了。

But, 当停止一个操作的时候,有很多后续操作需要执行,你可能需要用到CancellationToken`s Register方法,这时候使用协作式取消来的简明了吧。

代码下载

下期预告:更改UI 同步上下文TaskSchedule VS 线程池的TaskSchedule

转载于:https://www.cnblogs.com/lnetmor/archive/2012/02/02/2335781.html

Thread 编程:简明(1) - 协作式取消 VS 线程终止相关推荐

  1. java 并发编程第七章:取消和关闭

    Java没有提供任何机制来安全地终止线程,虽然Thread.stop和suspend等方法提供了这样的机制,但是存在严重的缺陷,应该避免使用这些方法.但是Java提供了中断Interruption机制 ...

  2. Linux C实现用户态协作式多线程!

    皮鞋?湿,不会胖,下雨也不怕!但皮鞋老板不让老湿说协程,那老湿就不说了,毕竟也真的不懂. 前天半夜写下一篇文章作为对九年前一个疑问的回应: Linux C实现纯用户态抢占式多线程!: https:// ...

  3. Vbs脚本编程简明教程之三

    Vbs 脚本编程简明教程之三 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" ...

  4. java 中的锁 aqs_Java并发编程系列-(4) 显式锁与AQS

    4 显示锁和AQS 4.1 Lock接口 核心方法 Java在java.util.concurrent.locks包中提供了一系列的显示锁类,其中最基础的就是Lock接口,该接口提供了几个常见的锁相关 ...

  5. java程序设计简明教程张晓龙_Java网络编程简明教程

    Java网络编程简明教程 网络编程 计算机网络相关概念 计算机网络是两台或更多的计算机组成的网络,同一网络内的任意两台计算机可以直接通信,所有计算机必须遵循同一种网络协议. 互联网 互联网是连接计算机 ...

  6. Linux下thread编程

    From: http://blog.sina.com.cn/s/blog_602f87700100dqmk.html Linux下thread编程(一) Sam前些天在提供一个库给别的公司时,因为不喜 ...

  7. 响应式编程(反应式编程)的来龙去脉(同步编程、多线程编程、异步编程再到响应式编程)

    响应式编程的来龙去脉(同步编程.多线程编程.异步编程再到响应式编程) 文章目录 响应式编程的来龙去脉(同步编程.多线程编程.异步编程再到响应式编程) 简介 1. 示例 2. 同步编程 3. 多线程编程 ...

  8. UR5协作式机器人自动铣削和码垛加热元件

    短篇案例:   AQUAEL是全球水产业的先进企业,该公司在其规模颇大的波兰苏瓦乌基部署了UR5协作式机器人,这些机器人每天的工作任务是自动加工为水族馆设计的加热元件.协作式机器人缩短了生产时间,并让 ...

  9. Missive for mac(协作式电子邮件客户端)

    Missive Mac版是Mac平台上的一款协作式电子邮件客户端.为用户提供了及时沟通.团队交流.邮件发送.文件处理等众多功能,用户可以使用软件查看自己的邮件历史以便存储和使用重要的办公信息.本站现在 ...

  10. XWiki 11.1 发布,协作式应用开发平台

    XWiki 11.1 发布了,XWiki 是一个用 Java 编写的开源 wiki 和应用平台.它的开发平台特性允许创建协作式 Web 应用,同时也提供了构建于平台之上的打包应用(第二代 wiki,又 ...

最新文章

  1. CMU赵越:关于数据挖掘的分享!
  2. java 文件md5校验_Java 获取 文件md5校验码
  3. vs code设置支持jsx支持emmet
  4. expecting statement错误的一种情况(phpstorm 8.0.2)
  5. Java异常面试问题
  6. Linux中几个实用快捷键
  7. TIM SWEENEY:引擎及图形学的未来
  8. 如果估算IT的测试Pattern数
  9. 微信公众号根据URL取文章详情 API 返回值说明
  10. 河北省第三届研究生数学建模B题(二等)交通检测器数据质量控制及预测
  11. 微信公众号后台接口文档
  12. vscode运行命令是报错:标记“”不是此版本中的有效语句分隔符。
  13. xcode 翻新工程_18个著名网站的酷概念设计(翻新)
  14. Dockerfile unable to access ‘.git/‘: Failed to connect to gitlab.com
  15. 一篇文章搞定DX9.0c 环境里的3DXSpriet !!
  16. UIQ来电监听挂断原理和代码
  17. python之正则表达式(基础篇)
  18. DJ无人机延时摄影后处理
  19. 本地提交到github时出现错误
  20. (Linux)在Ubuntu系统中添加新用户并授予root权限

热门文章

  1. LAMP-各PHP加速器性能剖析
  2. Design Patterns(二十四):Visite Pattern--VB代码
  3. null和空的区别 oracle,Oracle中NULL与空字符串''的区别的总结
  4. java 文件下载 并发_高并发下载tomcat下的文件时,发生java.net.SocketException: Connection reset解决方案...
  5. mysql可以复用删除的记录吗_MySQL学习(八)删除表数据
  6. python 自动赚钱软件排行榜_微任务兼职平台app下载
  7. 能给别人吗_《奇葩说》观点引热议:一种能看透别人心思的能力,你敢要吗?...
  8. JVM学习01—下载编译openjdk源码并进行调试
  9. mysql安装包提示选项_Windows操作系统安装MySQL解压版
  10. kafka依赖_Kafka集群搭建及必知必会