.NET并行编程 - 并行方式
使用多线程可以利用多核CPU的计算能力,可以提供更好的程序响应能力,但是每个线程都有开销,需要注意控制线程的数量。
1. System.Threading.Thread
使用多线程最直接的是使用System.Threading.Thread。回调函数可以接受一个参数、或者不接受参数,没有返回值。
Thread t = new Thread(Echo);
t.Start("test");
t.Join();
t = new Thread(DoSomeThing);
t.Start();
private static void Echo(object obj)
{
Console.WriteLine(obj);
Thread.Sleep(100);
}
private static void DoSomeThing()
{
Console.WriteLine("DoSomeThing, threadid={0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(100);
}
2. 线程池
创建和销毁线程需要大量的时间,太多的线程还会消耗大量的内存。使用线程池可以重用线程,方便线程的管理。每个CLR有一个线程池,里面的线程分为Worker和IO线程。
回调函数只能是接受一个参数的函数,没有返回值。
ThreadPool.QueueUserWorkItem(Echo, "test2");
3. 取消
使用CancellationTokenSource和对应的CancellationToken实现协作式取消,CancellationToken是结构类型,包含对CancellationTokenSource的引用。CancellationTokenSource封装了数据,CancellationToken封装了操作。每个线程都有自己的Token,但是访问同一个Source,通过改变Source的状态,可以通知所有监测Token的线程。
CancellationTokenSource cts1 = new CancellationTokenSource();
cts1.Token.Register(
() =>
{
Console.WriteLine("cts1 canceled, threadid={0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(100);
});
CancellationTokenSource cts2 = new CancellationTokenSource();
cts2.Token.Register(
() =>
{
Console.WriteLine("cts2 canceled, threadid={0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(100);
});
var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token);
linkedCts.Token.Register(
() =>
{
Console.WriteLine("linkedCts cancled, threadid={0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(100);
});
Task.Factory.StartNew(
() =>
{
Thread.Sleep(100);
if (cts1.Token.IsCancellationRequested)
{
Console.WriteLine("Canceled. threadid={0}", Thread.CurrentThread.ManagedThreadId);
}
});
cts1.Cancel();
4. Task
线程池的任务没有办法知道状态,也没有返回值。Task建立在线程池基础上,提供了这些功能。
var t = new Task<int>(sum, 20);
t.Start();
Console.WriteLine(t.Result);
Task用法的一个例子。包括TaskFactory,Cancel,ContinueWith
Task parent = new Task(
() =>
{
CancellationTokenSource cts = new CancellationTokenSource();
TaskFactory<int> tf = new TaskFactory<int>(
cts.Token,
TaskCreationOptions.AttachedToParent,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default);
var childTasks = new[]
{
tf.StartNew(() => sum(cts.Token, 1000)),
tf.StartNew(() => sum(cts.Token, 2000)),
tf.StartNew(() => sum(cts.Token, int.MaxValue))
};
for (int i = 0; i < childTasks.Length; i++)
{
childTasks[i].ContinueWith(t => cts.Cancel(), TaskContinuationOptions.OnlyOnFaulted);
}
tf.ContinueWhenAll(
childTasks,
completedTasks =>
completedTasks.Where(t => !t.IsFaulted && !t.IsCanceled).Max(t => t.Result),
CancellationToken.None)
.ContinueWith(
t => Console.WriteLine("The max is {0}", t.Result),
TaskContinuationOptions.ExecuteSynchronously);
});
parent.ContinueWith(
p =>
{
StringBuilder sb =
new StringBuilder(
string.Format("Following exception(s) occurred. {0}", Environment.NewLine));
foreach (var e in p.Exception.Flatten().InnerExceptions)
{
sb.AppendLine(string.Format(" {0}: {1}", e.GetType(), e.Message));
}
Console.WriteLine(sb.ToString());
},
TaskContinuationOptions.OnlyOnFaulted);
parent.Start();
5. APM(Aync Programming Model)
.NET并行编程 - 并行方式的更多相关文章
- 四、并行编程 - 并行LINQ(PLINQ) 的使用。AsParallel
用于对内存中的数据做并行运算,也就是说其只支持 LINQ to Object 的并行运算 一.AsParallel(并行化) 就是在集合后加个AsParallel(). 例如: , ); == ); ...
- .Net并行编程
1.什么是线程?线程和进程的区别是什么? 线程是程序执行的最小单元. 区别: 进程是操作系统进行资源处理和分配的最小单位,而一个进程可以包含多个线程,并共享进程的资源. 2.什么是多线程?为什么设计多 ...
- 三、并行编程 - Task同步机制。TreadLocal类、Lock、Interlocked、Synchronization、ConcurrentQueue以及Barrier等
在并行计算中,不可避免的会碰到多个任务共享变量,实例,集合.虽然task自带了两个方法:task.ContinueWith()和Task.Factory.ContinueWhenAll()来实现任务串 ...
- 二、并行编程 - Task任务
任务,基于线程池.其使我们对并行编程变得更简单,且不用关心底层是怎么实现的.System.Threading.Tasks.Task类是Task Programming Library(TPL)中最核心 ...
- 一、并行编程 - 数据并行 System.Threading.Tasks.Parallel 类
一.并行概念 1.并行编程 在.NET 4中的并行编程是依赖Task Parallel Library(后面简称为TPL) 实现的.在TPL中,最基本的执行单元是task(中文可以理解为"任 ...
- Java中的函数式编程(八)流Stream并行编程
写在前面 在本系列文章的第一篇,我们提到了函数式编程的优点之一是"易于并发编程". Java作为一个多线程的语言,它通过 Stream 来提供了并发编程的便利性. 题外话: 严格来 ...
- .Net中的并行编程-2.ConcurrentStack的实现与分析
在上篇文章<.net中的并行编程-1.基础知识>中列出了在.net进行多核或并行编程中需要的基础知识,今天就来分析在基础知识树中一个比较简单常用的并发数据结构--.net类库中无锁栈的实现 ...
- .Net中的并行编程-3.ConcurrentQueue实现与分析
在上文<.Net中的并行编程-2.ConcurrentQueue的实现与分析> 中解释了无锁的相关概念,无独有偶BCL提供的ConcurrentQueue也是基于原子操作实现, 由于Con ...
- C#~异步编程再续~大叔所理解的并行编程(Task&Parallel)
返回目录 并行这个概念出自.net4.5,它被封装在System.Threading.Tasks命名空间里,主要提供一些线程,异步的方法,或者说它是对之前Thread进行的二次封装,为的是让开发人员更 ...
随机推荐
- JavaScript构造函数学习笔记
1 理解Javascript constructor实现原理 在 JavaScript 中,每个函数都有名为“prototype”的属性,用于引用原型对象.此原型对象又有名为“constructor” ...
- rand & random & arc4random
rand(3) / random(3) / arc4random(3) / et al. Written by Mattt Thompson on August 12th, 2013 What pas ...
- Oracle优化总结
本文主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了ORACLE数据库的优化调整方案.关键词 ORACLE数据库 环境调整 ...
- 《深入浅出Node.js》第7章 网络编程
@by Ruth92(转载请注明出处) 第7章 网络编程 Node 只需要几行代码即可构建服务器,无需额外的容器. Node 提供了以下4个模块(适用于服务器端和客户端): net -> TCP ...
- MSP430 IO 使用
MSP430内部上拉下拉使用注意——IO口测高低电平 MSP430单片机IO口用来检测高低电平时,是不需要外部上拉下拉的,因为其内部有上拉和下拉.在用作高低电平检测时,需要开启上拉或下拉. ...
- How to build the theory on a specific system - may be just a brain storm[clue found]
Motivation An observation and thoughts on reading Tel G.. Introduction to Distributed Algorithm(seco ...
- JQuery EasyUI DataGrid常用操作及注意事项(未完)
1.获取当前选中行,如果没有选中行,则返回 null var row = $('#gridID').datagrid('getSelected'); 2.获取当前所有选中行数据,返回的是选择的数组数据 ...
- 获取地址上的ID(页面与服务器的交互)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 优先队列 :Priority Queue
PriorityQueue是从JDK1.5开始提供的新的数据结构接口,它是一种基于优先级堆的极大优先级队列.优先级队列是不同于先进先出队列的另一种队列. 每次从队列中取出的是具有最高优先权的元素.如果 ...
- POSTGRES与JDBC对照
POSTGRES与JDBC对照 未经验证,仅供参考.