C#线程安全使用(四)
这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来。
这里主要讲解下CancellationTokenSource,CancellationTokenSource是用于取消线程,具体使用起来有点另类:首先定义实体,然后将其下的属性ToKen传递给线程,当需要取消线程时,调用下Cancel()方法。例子我依然采用了MSDN的例子,但我做了一些修改,这个例子虽然看起来挺复杂,但还是记录了许多内容。
由于不好理解,我就粗略讲解下:
Task<double> fTask = factory.ContinueWhenAll(tasks.ToArray(), 上面是创建任务,创建10个线程,并且线程中增加了判断,如果随即数等于0就取消该线程。
再介绍下factory.ContinueWhenAll,他包含两个参数Task[] tasks,
Action<Task[]> continuationAction。MSDN的解释是:
ContinueWhenAll 方法执行 continuationAction 委托,在 tasks 数组的所有任务完成后,无论它们的完成状态。
MSDN上就这个翻译的还不错,其他的基本可以无视了。。。
继续看代码,代码中增加了try catch,这是为什么呢,看下ContinueWhenAll英文解释:
The exception that is thrown when the tasks array is empty
这里千万不能看中文解释,不然你会凌乱的。看了英文解释就懂了,让任务为空就抛异常。
那么为什么任务为空呢,因为任务已经被取消了啊,所以为空了。具体代码如下。
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
// Define the cancellation token.
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
Random rnd = new Random();
Object lockObj = new Object();
List<Task<int[]>> tasks = new List<Task<int[]>>();
TaskFactory factory = new TaskFactory(token);
for (int taskCtr = ; taskCtr <= ; taskCtr++)
{
int iteration = taskCtr + ;
tasks.Add(factory.StartNew(() =>
{
int value;
int[] values = new int[];
for (int ctr = ; ctr <= ; ctr++)
{
lock (lockObj)
{
value = rnd.Next(, );
}
if (value == )
{
source.Cancel();
Console.WriteLine("Cancelling at task {0}", iteration);
break;
} values[ctr - ] = value;
}
Console.WriteLine("NO Cancel at task {0}", iteration);
return values;
}, token));
}
try
{
Task<double> fTask = factory.ContinueWhenAll(tasks.ToArray(),
(results) =>
{
Console.WriteLine("Calculating overall mean...");
long sum = ;
int n = ;
foreach (var t in results)
{
foreach (var r in t.Result)
{
sum += r;
n++;
}
}
return sum / (double)n;
}, token);
Console.WriteLine("The mean is {0}.", fTask.Result);
}
catch (AggregateException ae)
{
foreach (Exception e in ae.InnerExceptions)
{
if (e is TaskCanceledException)
Console.WriteLine("Unable to compute mean: {0}",
((TaskCanceledException)e).Message);
else
Console.WriteLine("Exception: " + e.GetType().Name);
}
}
Console.ReadLine(); }
}
显示结果图片,每次的结果都不一样的,所以我也是运行了好几次,看这个结果会发现一件事,线程只执行了两个,即当线程2中调用Cancel后,其他线程也被取消了。

----------------------------------------------------------------------------------------------------
注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!

C#线程安全使用(四)的更多相关文章
- {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器
Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...
- juc线程池原理(四): 线程池状态介绍
<Thread之一:线程生命周期及五种状态> <juc线程池原理(四): 线程池状态介绍> 线程有5种状态:新建状态,就绪状态,运行状态,阻塞状态,死亡状态.线程池也有5种状态 ...
- Java-五种线程池,四种拒绝策略,三种阻塞队列(转)
Java-五种线程池,四种拒绝策略,三种阻塞队列 三种阻塞队列: BlockingQueue<Runnable> workQueue = null; workQueue = n ...
- Java之创建线程的方式四:使用线程池
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.c ...
- Java 线程总结(十四)
1.在异步任务进程中,一种常见的场景是,主线程提交多个异步任务,然后希望有任务完成就处理结果,并且按任务完成顺序逐个处理,对于这种场景,Java 并发包提供了一个方便的方法,使用 Completion ...
- java并发编程(四)守护进程 线程阻塞的四种情况
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17099981 守护线程 Java中有两类线程:User Thread(用户线程).Da ...
- 关于windows线程同步的四种方法
#include "stdafx.h" #include "iostream" #include "list" #include " ...
- 转:【Java并发编程】之四:守护线程与线程阻塞的四种情况
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17099981 守护线程 Java中有两类线程:User Thread(用户线 ...
- delphi 线程教学第四节:多线程类的改进
第四节:多线程类的改进 1.需要改进的地方 a) 让线程类结束时不自动释放,以便符合 delphi 的用法.即 FreeOnTerminate:=false; b) 改造 Create 的参数 ...
- C++线程同步的四种方式(Windows)
为什么要进行线程同步? 在程序中使用多线程时,一般很少有多个线程能在其生命期内进行完全独立的操作.更多的情况是一些线程进行某些处理操作,而其他的线程必须对其处理结果进行了解.正常情况下对这种处理结果的 ...
随机推荐
- Pandas 0 数据结构Series
# -*- encoding:utf-8 -*- # Copyright (c) 2015 Shiye Inc. # All rights reserved. # # Author: ldq < ...
- leetcode 902 数位dp 不包含0
复习了一下数位dp 肯定不包含0,但是通常数位dp最后计算的结果较小的是包含前导0的,只是没显示出来而已,所以这题需要前导0,但是非前导0是不需要算进去的,因此,加个是否是前导0的状态即可 class ...
- SpringBoot加Poi仿照EasyPoi实现Excel导出
POI提供API给Java程序对Microsoft Office格式档案读和写的功能,详细功能可以直接查阅API,因为使用EasyPoi过程中总是缺少依赖,没有搞明白到底是什么坑,索性自己写一个简单工 ...
- IntelliJ IDEA:创建Java Web工程
- Gcd&Exgcd算法学习小记
Preface 对于许多数论问题,都需要涉及到Gcd,求解Gcd,常常使用欧几里得算法,以前也只是背下来,没有真正了解并证明过. 对于许多求解问题,可以列出贝祖方程:ax+by=Gcd(a,b),用E ...
- js数据类型以及数组字符串常用方法
JS判断数据类型 例子: var a = "iamstring."; var b = 222; var c= [1,2,3]; var d = new Date(); var e ...
- XGBoost原理和公式推导
本篇文章主要介绍下Xgboost算法的原理和公式推导.关于XGB的一些应用场景在此就不赘述了,感兴趣的同学可以自行google.下面开始: 1.模型构建 构建最优模型的方法一般是最小化训练数据的损失 ...
- H5 _浏览器通知功能使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 什么是 ajax?----异步 javascript 和 xml
GET 用于请求服务器数据 POST 用于上传数据到服务器,或者修改服务器数据 ajax 异步通信,实现页面的局部刷新,按需获取数据,节约带宽,带来更好的用户体验 客户端与服务器在不必刷新浏览器的情况 ...
- SSIS - 9.文件系统任务
文件系统任务是用来操作服务器上的文件和目录的.比如,可以新建任务来创建.复制.删除或移动一个文件或一个目录. 一.操作和属性 一个文件系统可以定义如下10种操作. 所有的操作包含Name, Descr ...