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
请按任意键继续. . .













目录
相关文章
|
3月前
|
存储 Oracle Java
|
5月前
|
Java
创建线程的方法
Java中实现多线程有四种方式:1. 继承Thread类,简单但占用继承机会,耦合度高;2. 实现Runnable接口,推荐方式,任务与线程解耦,支持Lambda;3. 实现Callable接口配合FutureTask,可获取返回值和异常;4. 使用线程池(ExecutorService),企业推荐,管理线程生命周期,提升性能,支持多种线程池类型。
151 1
|
6月前
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
431 5
|
6月前
|
机器学习/深度学习 监控 算法
局域网行为监控软件 C# 多线程数据包捕获算法:基于 KMP 模式匹配的内容分析优化方案探索
本文探讨了一种结合KMP算法的多线程数据包捕获与分析方案,用于局域网行为监控。通过C#实现,该系统可高效检测敏感内容、管理URL访问、分析协议及审计日志。实验表明,相较于传统算法,KMP在处理大规模网络流量时效率显著提升。未来可在算法优化、多模式匹配及机器学习等领域进一步研究。
203 0
|
JSON 程序员 C#
使用 C# 比较两个对象是否相等的7个方法总结
比较对象是编程中的一项基本技能,在实际业务中经常碰到,比如在ERP系统中,企业的信息非常重要,每一次更新,都需要比较记录更新前后企业的信息,直接比较通常只能告诉我们它们是否指向同一个内存地址,那我们应该怎么办呢?分享 7 个方法给你!
499 2
|
C# UED SEO
C# 异步方法async / await任务超时处理
通过使用 `Task.WhenAny`和 `Task.Delay`方法,您可以在C#中有效地实现异步任务的超时处理机制。这种方法允许您在指定时间内等待任务完成,并在任务超时时采取适当的措施,如抛出异常或执行备用操作。希望本文提供的详细解释和代码示例能帮助您在实际项目中更好地处理异步任务超时问题,提升应用程序的可靠性和用户体验。
558 3
|
12月前
|
缓存 安全 Java
【JavaEE】——单例模式引起的多线程安全问题:“饿汉/懒汉”模式,及解决思路和方法(面试高频)
单例模式下,“饿汉模式”,“懒汉模式”,单例模式下引起的线程安全问题,解锁思路和解决方法
|
12月前
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
259 3
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
145 2

热门文章

最新文章