C#多线程实现方法——Task/Task.Factary

简介: 原文:C#多线程实现方法——Task/Task.FactaryTask 使用 Task以及Task.Factory都是在.Net 4引用的。Task跟Thread很类似,通过下面例子可以看到。 static public void ThreadMain() ...
原文: 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
请按任意键继续. . .













目录
相关文章
|
1月前
|
Java 调度 C#
C#学习系列相关之多线程(一)----常用多线程方法总结
C#学习系列相关之多线程(一)----常用多线程方法总结
|
1月前
|
C#
C#学习相关系列之数组---常用方法使用(二)
C#学习相关系列之数组---常用方法使用(二)
|
6天前
使用代理IP池实现多线程的方法
使用代理IP池实现多线程的方法
|
26天前
|
Java 测试技术 Python
Python开启线程和线程池的方法
Python开启线程和线程池的方法
17 0
Python开启线程和线程池的方法
|
1月前
|
数据处理 调度 开发者
QML多线程魔法:探索不同方法,提升性能
QML多线程魔法:探索不同方法,提升性能
177 0
|
1月前
|
C#
C#学习系列相关之多线程(二)----Thread类介绍
C#学习系列相关之多线程(二)----Thread类介绍
|
1月前
|
C#
C#学习相关系列之数据类型类----嵌套类和嵌套方法(三)
C#学习相关系列之数据类型类----嵌套类和嵌套方法(三)
|
16天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
27天前
|
存储 缓存 NoSQL
Redis单线程已经很快了6.0引入多线程
Redis单线程已经很快了6.0引入多线程
31 3
|
30天前
|
消息中间件 安全 Linux
线程同步与IPC:单进程多线程环境下的选择与权衡
线程同步与IPC:单进程多线程环境下的选择与权衡
58 0