C#多线程实现方法——Task/Task.Factary
原文:C#多线程实现方法——Task/Task.Factary
Task
使用
Task以及Task.Factory都是在.Net 4引用的。Task跟Thread很类似,通过下面例子可以看到。
static public void ThreadMain()
{
Thread t1 = new Thread(TaskWorker);
t1.Start(3);
} static public void TaskMain()
{
Task t1 = new Task(TaskWorker, 3, TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent);
Console.WriteLine(t1.Status);
t1.Start();
t1.Wait(); // need to wait for finishing.
} static public void TaskWorker(object state)
{
int nTime = (int)state;
for (int i = 0; i < nTime; i++)
{
Thread.Sleep(100);
Console.WriteLine(string.Format("current thread {0} sleep for {1} miniseconds .", Task.CurrentId, (i + 1) * 100));
}
return;
}
我们看到TaskWorker都是用于Task以及Thread,都是只能接受一个参数(Action<object>),不过task可以支持工作函数具有返回值(Func<TRessult>()或者Func<object, TResult>)。但是弱的类型输入跟thread一样。Task提供返回值是为了后面说到的task结构层次有用。
下面是调用一个具有返回值的工作函数
static public int TaskWorkerWithReturn(object state)
{
int nTime = (int)state;
for (int i = 0; i < nTime; i++)
{
Thread.Sleep(100);
Console.WriteLine(string.Format("current thread {0} sleep for {1} miniseconds .", Task.CurrentId, (i + 1) * 100));
}
nTime++;
return nTime;
}
主调函数为:
Task<int> t2 = new Task<int>(TaskWorkerWithReturn, 3, TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent);
t2.Start();
t2.Wait();
Console.WriteLine(t2.Result);
不管从工作函数是否有返回值,task都需要在其运行过程中至少有一个前台线程在跑,否则会直接退出,根本原因是所有task都是后台线程。task的工作函数的输入参数类型职能是object。
同步
对于没有返回值的工作函数需要通过内核对象来同步主调线程(例如task内置的事件,使用wait来阻塞等待);
对于有返回值的工作函数可以通过访问其Result函数来实现阻塞等待。
static public int TaskWorkerWithReturn(object state)
{
int nTime = (int)state;
for (int i = 0; i < nTime; i++)
{
Thread.Sleep(100);
Console.WriteLine(string.Format("current thread {0} sleep for {1} miniseconds .", Task.CurrentId, (i + 1) * 100));
}
nTime++;
return nTime;
}
主调函数:
Task<int> t2 = new Task<int>(TaskWorkerWithReturn, 3, TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent);
t2.Start();
Console.WriteLine("t2:" + t2.Result);
异步调用
作为新的一个特性在.net 4中引入,task能实现丰富的异步调用,使用成员函数ContinueWith来响应异步工作函数的完成,注意,不一定由之前完成异步函数的线程执行。
static public void TaskMain()
{
Task<int> t3 = new Task<int>(FirstTask, 1);
t3.Start();
Task<int> t4 = t3.ContinueWith<int>(RecusiveTask);
Task<int> t5 = t4.ContinueWith<int>(RecusiveTask);
Task<int> t6 = t5.ContinueWith<int>(RecusiveTask).ContinueWith<int>(RecusiveTask);
//Console.WriteLine(string.Format("final result: {0}", t6.Result));
} static public int FirstTask(object state)
{
int data = (int)state;
for (int i = 0; i < data; i++)
{
Thread.Sleep(100);
Console.WriteLine(string.Format("current thread {0} slept for {1} milisecond.", Task.CurrentId, (i + 1) * 100));
}
data++;
return data;
} static public int RecusiveTask(Task<int> T)
{
int data = T.Result;
for (int i = 0; i < data; i++)
{
Thread.Sleep(100);
Console.WriteLine(string.Format("current thread {0} slept for {1} milisecond.", Task.CurrentId, (i + 1) * 100));
}
data++;
return data;
}
输出结果为:
current thread 1 slept for 100 milisecond.
current thread 2 slept for 100 milisecond.
current thread 2 slept for 200 milisecond.
current thread 3 slept for 100 milisecond.
current thread 3 slept for 200 milisecond.
current thread 3 slept for 300 milisecond.
current thread 4 slept for 100 milisecond.
current thread 4 slept for 200 milisecond.
current thread 4 slept for 300 milisecond.
current thread 4 slept for 400 milisecond.
current thread 5 slept for 100 milisecond.
current thread 5 slept for 200 milisecond.
current thread 5 slept for 300 milisecond.
current thread 5 slept for 400 milisecond.
current thread 5 slept for 500 milisecond.
final result: 6
请按任意键继续. . .
C#多线程实现方法——Task/Task.Factary的更多相关文章
- 多线程随笔二(Task)
Task类是.net 4.0新加进来的特性,对原有的Thread,ThreadPool做了进一步的封装,使得.net平台上的多线程编程变得更加方便.废话不多说,进入正题. 一. Task启动 Task ...
- 多线程系列(3)任务Task
虽然使用线程池ThreadPool让我们使用多线程变得容易,但是因为是由系统来分配的,如果想对线程做精细的控制就不太容易了,比如某个线程结束后执行一个回调方法.恰好Task可以实现这样的需求.这篇文章 ...
- 多线程之旅(Task 任务)
一.Task(任务)和ThreadPool(线程池)不同 源码 1.线程(Thread)是创建并发工具的底层类,但是在前几篇文章中我们介绍了Thread的特点,和实例.可以很明显发现局限性 ...
- [深入学习C#]C#实现多线程的方式:Task——任务
简介 .NET 4包含新名称空间System.Threading.Tasks,它 包含的类抽象出了线程功能. 在后台使用ThreadPool. 任务表示应完成的某个单元的工作. 这个单元的工作可以在单 ...
- C#实现多线程的方式:Task——任务
简介 .NET 4包含新名称空间System.Threading.Tasks,它 包含的类抽象出了线程功能. 在后台使用ThreadPool. 任务表示应完成的某个单元的工作. 这个单元的工作可以在单 ...
- Linux内核多线程实现方法 —— kthread_create函数【转】
转自:http://blog.csdn.net/sharecode/article/details/40076951 Linux内核多线程实现方法 —— kthread_create函数 内核经常需要 ...
- 详细分析 Java 中实现多线程的方法有几种?(从本质上出发)
详细分析 Java 中实现多线程的方法有几种?(从本质上出发) 正确的说法(从本质上出发) 实现多线程的官方正确方法: 2 种. Oracle 官网的文档说明 方法小结 方法一: 实现 Runnabl ...
- C# 多线程限制方法调用(monitor)
多线程执行方法 改方法没有执行完时 别的方法不能调用次方法.用循环执行一个方法可以需要一分钟 在这一分钟只内任何 成员都不能再调用该方法. class MonitorSample { ; //生产者和 ...
- Java并发编程(一) 两种实现多线程的方法(Thread,Runnable)
Java中实现多线程的方法有两种: 继承Thread类和实现Runnable方法,并重写Run方法,然后调用start()方法启动线程.使用Runnable会比Thread要好很多,主要是以下三个原因 ...
随机推荐
- Oracle 数据的导入和导出(SID service.msc)
一:版本号说明: (1)(Oracle11 32位系统)Oracle - OraDb11g_home1: (2)成功安装后显演示样例如以下:第一个图是管理工具.创建连接.创建表:第二个是数据库创建工 ...
- Python标准库:内置函数repr(object)
本函数是返回对象object的具体说明字符串. 样例: #repr() print(repr(range(5))) print(repr(help)) print(repr(0x200)) print ...
- Android新增API之AudioEffect中文API与应用实例
在Android2.3中增加了对音频混响的支持,这些API包含在android.media.audiofx包中. 一.概述 AudioEffect是android audio framework(an ...
- 管理tips
管理是什么? 我认为达到的目的就是高效.低成本. 成本低才能有盈余,才能活的长和舒服.高效就是无谓的消耗少,以结果为导向. 开源节流,应该包含显性的与隐性的两方面. 隐性成本: 1.会议成本;2.沟通 ...
- 开源软件实践之linux高性能服务器编程框架和选型
很多人学习编程技术一般都通过一本编程语言的入门书籍,然后尝试做一些例子和小项目.但是这些都不能让我们深入的学习很多的编程技巧和高深技术,当然这个时候很多有经验的学习人员就会告诉大家,找一个好的开源软件 ...
- awk 的逻辑运算字符
既然有需要用到 "条件" 的类别,自然就需要一些逻辑运算啰-例如底下这些:运算单元代表意义> 大于小于>= 大于或等于小于或等于== 等于!= 不等于值得注意的是那个 ...
- JVM调优总结(三)-基本垃圾回收算法
可以从不同的的角度去划分垃圾回收算法: 按照基本回收策略分 引用计数(Reference Counting): 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数. ...
- 分析内存使用情况 (JavaScript)
[此文档是初定版,随时可能进行更改.] JavaScript 内存分析器在 Visual Studio 2012 更新 1 和 Visual Studio 2013 中提供,旨在帮助你了解内存使用量和 ...
- 手游接入Facebook的那些坑
之前工作须要在手游中接入了facebook,并以此写了<手游接入Facebook功能>的博文.当时facebook sdk的版本号还是3.x.代码集成度比較低.集成起来也比較麻烦.文中仅仅 ...
- jQuery选择器——全新的总结方式
jQuery 选择器的总结 用于定位的选择器: 基本选择器:(用来进行绝对定位) $("#myELement") 选择id值等于myElement的元素,id值不能重复在文档 ...