iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C#多线程编程Task用法详解
  • 966
分享到

C#多线程编程Task用法详解

2024-04-02 19:04:59 966人浏览 泡泡鱼
摘要

目录一、基本概念Task优势二、Task用法创建任务1、使用Task创建无返回值2、使用Task.Run方法创建任务3、使用Factory方式创建任务4、创建带返回值的Task三、常

一、基本概念

Task优势

ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便,例如:

  • ThreadPool不支持线程的取消、完成、失败通知等交互性操作;
  • ThreadPool不支持线程执行的先后次序;

.net Framework 在4.0的时候提供了一个功能更强大的概念:Task。Task在ThreadPool的基础上进行了优化,并提供了更多的api。看下面一个简单的示例:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TaskDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建Task
            Task t = new Task(() => 
            {
                Console.WriteLine("任务开始工作.....");
                Thread.Sleep(5000);
            });
            // 启动
            t.Start();
            t.ContinueWith((task) => 
            {
                Console.WriteLine("任务完成,完成时候的状态为:");
                Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted);
            });
            Console.WriteLine("启动");
            Console.ReadKey();
        }
    }
}

二、Task用法

创建任务

Task创建的任务可以分为有返回值和无返回值两种。

1、使用Task创建无返回值

先看一下Task的定义:

可以看到Task构造函数的参数是Action委托。所以使用Task创建任务的代码如下:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TaskDemo
{
    class Program
    {
        static void Main(string[] args)
        {

            #region 1、使用Task创建任务
            Task task = new Task(() => TaskMethod("Task 1"));
            Console.WriteLine("before start status:"+task.Status);
            // Task创建的任务必须调用start方法才能启动
            task.Start();
            Console.WriteLine("after start status:" + task.Status);
            #endregion
            Console.ReadKey();
        }

        static void TaskMethod(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
        }
    }
}

程序运行结果:

注:任务的状态,Start之前为Created,Start之后为WaitingToRun。

2、使用Task.Run方法创建任务

Task.Run创建的任务可以执行启动:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TaskDemo
{
    class Program
    {
        static void Main(string[] args)
        {

            #region 1、使用Task创建任务
            //Task task = new Task(() => TaskMethod("Task 1"));
            //Console.WriteLine("before start status:"+task.Status);
            //// Task创建的任务必须调用start方法才能启动
            //task.Start();
            //Console.WriteLine("after start status:" + task.Status);
            #endregion

            #region 2、使用Task.Run创建任务
            Task.Run(() => TaskMethod("Task Run"));
            #endregion
            Console.ReadKey();
        }

        static void TaskMethod(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
        }
    }
}

程序运行结果:

3、使用Factory方式创建任务

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TaskDemo
{
    class Program
    {
        static void Main(string[] args)
        {

            #region 1、使用Task创建任务
            //Task task = new Task(() => TaskMethod("Task 1"));
            //Console.WriteLine("before start status:"+task.Status);
            //// Task创建的任务必须调用start方法才能启动
            //task.Start();
            //Console.WriteLine("after start status:" + task.Status);
            #endregion

            #region 2、使用Task.Run创建任务
            // Task.Run(() => TaskMethod("Task Run"));
            #endregion

            #region 3、使用Factory创建任务
            // 使用Task.Factory创建
            Task.Factory.StartNew(() => TaskMethod("Task 4"));
            //标记为长时间运行任务,则任务不会使用线程池,而在单独的线程中运行。
            Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);

            // 实例化TaskFactory对象,然后创建
            TaskFactory factory = new TaskFactory();
            factory.StartNew(() => TaskMethod("Task 6"));


            #endregion
            Console.ReadKey();
        }

        static void TaskMethod(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
        }
    }
}

程序运行结果:

4、创建带返回值的Task

代码如下:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TaskDemo
{
    class Program
    {
        static void Main(string[] args)
        {

            #region 1、使用Task创建任务
            //Task task = new Task(() => TaskMethod("Task 1"));
            //Console.WriteLine("before start status:"+task.Status);
            //// Task创建的任务必须调用start方法才能启动
            //task.Start();
            //Console.WriteLine("after start status:" + task.Status);
            #endregion

            #region 2、使用Task.Run创建任务
            // Task.Run(() => TaskMethod("Task Run"));
            #endregion

            #region 3、使用Task.Factory创建任务
            //Task.Factory.StartNew(() => TaskMethod("Task 4"));
            ////标记为长时间运行任务,则任务不会使用线程池,而在单独的线程中运行。
            //Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);
            #endregion

            #region 4、创建带返回值的任务
            TaskMethodReturn("Main Thread Task");
            // 创建带返回值的Task
            Task<int> task = CreateTask("Task 1");
            // 启动
            task.Start();
            // 获取返回值
            int result1 = task.Result;
            Console.WriteLine($"Task 1 Result is:{result1}");
            Task<int> task2 = new Task<int>(() => TaskMethodReturn("Task 2"));
            task2.Start();
            int result2 = task2.Result;
            Console.WriteLine($"Task 2 Result is:{result2}");
            int result3= Task.Run<int>(() => TaskMethodReturn("Task 3")).Result;
            Console.WriteLine($"Task 3 Result is:{result3}");
            int result4 = Task.Factory.StartNew<int>(() => TaskMethodReturn("Task 4")).Result;
            Console.WriteLine($"Task 4 Result is:{result4}");
            #endregion
            Console.ReadKey();
        }

        /// <summary>
        /// 返回一个Task<int>
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        static Task<int> CreateTask(string name)
        {
            // 参数是Func<int>
            return new Task<int>(() => TaskMethodReturn(name));
        }

        static void TaskMethod(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
        }

        static int TaskMethodReturn(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                   name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            return 42;
        }
    }
}

程序运行结果:

我们在文章开始的时候说过,Task是基于ThreadPool的,那么怎么证明呢?看下面的代码:

/// <summary>
/// 测试Task的线程来自于ThreadPool
/// </summary>
static void Test()
{
            // 设置线程池中最大的线程数
            ThreadPool.SetMaxThreads(6, 6);
            // 创建Task的集合
            List<Task> taskList = new List<Task>();
            // 创建int类型的集合,用于存放线程ID
            List<int> threadIdList = new List<int>();
            // 使用Task循环创建50个线程
            for (int i = 0; i < 30; i++)
            {
                int k = i;
                Task task = Task.Run(() => 
                {
                    // 当前线程ID加入到集合中
                    threadIdList.Add(Thread.CurrentThread.ManagedThreadId);
                    Console.WriteLine($"this is {k} 循环 ThreadID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
                    // 休眠
                    Thread.Sleep(200);
                });
                // 把task加入到集合中
                taskList.Add(task);
            }

            // 等待所有的线程执行完
            Task.WaitAll(taskList.ToArray());
            // 输出总数量
            Console.WriteLine($"线程总数:{threadIdList.Distinct().Count()}");
}

程序运行结果:

从结果中可以看出,Task中的线程确实是来自于ThreadPool。

三、常见方法

我们以下面的一个例子来讲解Task中比较常见的几个方法。多名开发者合作开发一个项目,每个人负责一个模块的开发,我们可以把这个过程认为是多线程,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace TaskDemo
{
    class Program
    {
        static void Main(string[] args)
        {

            #region 1、使用Task创建任务
            //Task task = new Task(() => TaskMethod("Task 1"));
            //Console.WriteLine("before start status:"+task.Status);
            //// Task创建的任务必须调用start方法才能启动
            //task.Start();
            //Console.WriteLine("after start status:" + task.Status);
            #endregion

            #region 2、使用Task.Run创建任务
            // Task.Run(() => TaskMethod("Task Run"));
            #endregion

            #region 3、使用Factory创建任务
            // 使用Task.Factory创建
            //Task.Factory.StartNew(() => TaskMethod("Task 4"));
            ////标记为长时间运行任务,则任务不会使用线程池,而在单独的线程中运行。
            //Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);

            // 实例化TaskFactory对象,然后创建
            //TaskFactory factory = new TaskFactory();
            //factory.StartNew(() => TaskMethod("Task 6"));
            #endregion

            #region 4、创建带返回值的任务
            //TaskMethodReturn("Main Thread Task");
            //// 创建带返回值的Task
            //Task<int> task = CreateTask("Task 1");
            //// 启动
            //task.Start();
            //// 获取返回值
            //int result1 = task.Result;
            //Console.WriteLine($"Task 1 Result is:{result1}");
            //Task<int> task2 = new Task<int>(() => TaskMethodReturn("Task 2"));
            //task2.Start();
            //int result2 = task2.Result;
            //Console.WriteLine($"Task 2 Result is:{result2}");
            //int result3= Task.Run<int>(() => TaskMethodReturn("Task 3")).Result;
            //Console.WriteLine($"Task 3 Result is:{result3}");
            //int result4 = Task.Factory.StartNew<int>(() => TaskMethodReturn("Task 4")).Result;
            //Console.WriteLine($"Task 4 Result is:{result4}");
            #endregion


            #region 测试Task线程是来自于ThreadPool

            // Test();
            #endregion

            // 合作开发项目,每个人负责一个模块,可以认为是多线程
            Console.WriteLine("开始合作开发一个大项目!");
            Task.Run(() => codingShow("Tom", "搭建微服务架构!"));
            Task.Run(() => CodingShow("Kevin", "微信接口!"));
            Task.Run(() => CodingShow("Jack", "搭建后台框架!"));
            Task.Run(() => CodingShow("Alex", "设计数据库!"));
            Task.Run(() => CodingShow("Lee", "支付宝接口对接!"));





            Console.ReadKey();
        }

        /// <summary>
        /// 返回一个Task<int>
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        static Task<int> CreateTask(string name)
        {
            // 参数是Func<int>
            return new Task<int>(() => TaskMethodReturn(name));
        }

        static void TaskMethod(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
        }

        static int TaskMethodReturn(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                   name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            return 42;
        }

        /// <summary>
        /// 测试Task的线程来自于ThreadPool
        /// </summary>
        static void Test()
        {
            // 设置线程池中最大的线程数
            ThreadPool.SetMaxThreads(6, 6);
            // 创建Task的集合
            List<Task> taskList = new List<Task>();
            // 创建int类型的集合,用于存放线程ID
            List<int> threadIdList = new List<int>();
            // 使用Task循环创建50个线程
            for (int i = 0; i < 30; i++)
            {
                int k = i;
                Task task = Task.Run(() =>
                {
                    // 当前线程ID加入到集合中
                    threadIdList.Add(Thread.CurrentThread.ManagedThreadId);
                    Console.WriteLine($"this is {k} 循环 ThreadID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
                    // 休眠
                    Thread.Sleep(200);
                });
                // 把task加入到集合中
                taskList.Add(task);
            }

            // 等待所有的线程执行完
            Task.WaitAll(taskList.ToArray());
            // 输出总数量
            Console.WriteLine($"线程总数:{threadIdList.Distinct().Count()}");
        }

        /// <summary>
        /// 模拟Coding过程
        /// </summary>
        /// <param name="name"></param>
        /// <param name="projectName"></param>
        static void CodingShow(string name, string projectName)
        {
            Console.WriteLine($"CodingShow Start  {name} {projectName}  {Thread.CurrentThread.ManagedThreadId.ToString("00")} ");
            long lResult = 0;
            for (int i = 0; i < 1_000_000_000; i++)
            {
                lResult += i;
            }

            Console.WriteLine($"CodingShow   End  {name} {projectName} {Thread.CurrentThread.ManagedThreadId.ToString("00")} ");
        }
    }
}

程序运行结果:

这时需求发生了变化,所有的模块都开发完成以后,开始搭建测试环境,修改代码如下:

// 合作开发项目,每个人负责一个模块,可以认为是多线程
Console.WriteLine("开始合作开发一个大项目!");
Task.Run(() => CodingShow("Tom", "搭建微服务架构!"));
Task.Run(() => CodingShow("Kevin", "微信接口!"));
Task.Run(() => CodingShow("Jack", "搭建后台框架!"));
Task.Run(() => CodingShow("Alex", "设计数据库!"));
Task.Run(() => CodingShow("Lee", "支付宝接口对接!"));
Console.WriteLine("所有模块都开发完成,开始搭建测试环境");

程序运行结果:

可以看到显然不是我们想要的结果,模块开发工作还没有结束就搭建测试环境,即子线程还没有结束,主线程就已经结束了。要想实现我们想要的效果,那么必须使主线程等待所有子线程都结束以后,主线程才能结束。

1、WaitAll()

WaitAll()表示等待所有的Task都执行完成。看WaitAll()的定义:

WaitAll()方法有很多重载,我们在这里使用第一个重载方法,即参数是Task[]数组。查看Run()方法的定义时,我们会发现Run()方法的返回值就是Task类型,我们使用WaitAll()修改上面的代码:

// 定义一个Task类型的集合
List<Task> taskList = new List<Task>();
Console.WriteLine("开始合作开发一个大项目!");
taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服务架构!")));
taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后台框架!")));
taskList.Add(Task.Run(() => CodingShow("Alex", "设计数据库!")));
taskList.Add(Task.Run(() => CodingShow("Lee", "支付宝接口对接!")));

// 等待所有模块都开发完成,才能搭建测试环境
Task.WaitAll(taskList.ToArray());
Console.WriteLine("所有模块都开发完成,开始搭建测试环境");

程序运行结果:

WaitAll()会使程序产生卡顿。

加载首页信息的时候可以使用WaitAll()方法。一个首页信息可能来自于几部分的数据,每一部分的数据对应一个线程,只有所有的线程都执行完毕才显示首页信息。

2、WaitAny()

这时需求又发生改变了:某一个模块开发完成以后就搭建测试环境。这时候就可以使用WaitAny()了。WaitAny()表示等待其中任何一个任务完成就会进入下一个任务,定义如下:

修改后的代码如下:

// 定义一个Task类型的集合
List<Task> taskList = new List<Task>();
Console.WriteLine("开始合作开发一个大项目!");
taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服务架构!")));
taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后台框架!")));
taskList.Add(Task.Run(() => CodingShow("Alex", "设计数据库!")));
taskList.Add(Task.Run(() => CodingShow("Lee", "支付宝接口对接!")));

// 等待所有模块都开发完成,才能搭建测试环境
Task.WaitAny(taskList.ToArray());
Console.WriteLine("有模块开发完成,开始搭建测试环境");

程序运行结果:

可以看到:设计数据库模块完成以后,就开始搭建测试环境了。如何需求。

WaitAny()会使程序产生卡顿。

有一个列表数据,数据可以来源于接口、缓存、数据库等,可以开启多个线程,只要有一个线程执行完毕就可以继续执行下面的步骤,这时就可以使用WaitAny()。

3、ContinueWhenAll()

WaitAll()会卡顿界面,那么有没有不卡顿界面的呢?ContinueWhenAll和WaitAll实现的效果一样,代码如下:

List<Task> taskList = new List<Task>();
Console.WriteLine("开始合作开发一个大项目!");
taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服务架构!")));
taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后台框架!")));
taskList.Add(Task.Run(() => CodingShow("Alex", "设计数据库!")));
taskList.Add(Task.Run(() => CodingShow("Lee", "支付宝接口对接!")));
TaskFactory factory = new TaskFactory();
factory.ContinueWhenAll(taskList.ToArray(), t => Console.WriteLine("所有模块开发完成"));

程序运行结果:

4、ContinueWhenAny

ContinueWhenAny实现的效果和WaitAny一样,ContinueWhenAny不会卡顿界面,代码如下:

List<Task> taskList = new List<Task>();
Console.WriteLine("开始合作开发一个大项目!");
taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服务架构!")));
taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后台框架!")));
taskList.Add(Task.Run(() => CodingShow("Alex", "设计数据库!")));
taskList.Add(Task.Run(() => CodingShow("Lee", "支付宝接口对接!")));
TaskFactory factory = new TaskFactory();
factory.ContinueWhenAny(taskList.ToArray(), t => Console.WriteLine("某一个模块开发完成"));

程序运行结果:

ContinueWhenAll()和ContinueWhenAny()都会开启一个新的线程。

5、ContinueWith

ContinueWith表示回调,代码如下:

Task.Run(() => { Console.WriteLine("任务执行完成"); }).ContinueWith(p=> 
{
      Task.Run(() => { Console.WriteLine("执行回调"); });
});

程序执行结果:

程序完整代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace TaskDemo
{
    class Program
    {
        static void Main(string[] args)
        {

            #region 1、使用Task创建任务
            //Task task = new Task(() => TaskMethod("Task 1"));
            //Console.WriteLine("before start status:"+task.Status);
            //// Task创建的任务必须调用start方法才能启动
            //task.Start();
            //Console.WriteLine("after start status:" + task.Status);
            #endregion

            #region 2、使用Task.Run创建任务
            // Task.Run(() => TaskMethod("Task Run"));
            #endregion

            #region 3、使用Factory创建任务
            // 使用Task.Factory创建
            //Task.Factory.StartNew(() => TaskMethod("Task 4"));
            ////标记为长时间运行任务,则任务不会使用线程池,而在单独的线程中运行。
            //Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);

            // 实例化TaskFactory对象,然后创建
            //TaskFactory factory = new TaskFactory();
            //factory.StartNew(() => TaskMethod("Task 6"));
            #endregion

            #region 4、创建带返回值的任务
            //TaskMethodReturn("Main Thread Task");
            //// 创建带返回值的Task
            //Task<int> task = CreateTask("Task 1");
            //// 启动
            //task.Start();
            //// 获取返回值
            //int result1 = task.Result;
            //Console.WriteLine($"Task 1 Result is:{result1}");
            //Task<int> task2 = new Task<int>(() => TaskMethodReturn("Task 2"));
            //task2.Start();
            //int result2 = task2.Result;
            //Console.WriteLine($"Task 2 Result is:{result2}");
            //int result3= Task.Run<int>(() => TaskMethodReturn("Task 3")).Result;
            //Console.WriteLine($"Task 3 Result is:{result3}");
            //int result4 = Task.Factory.StartNew<int>(() => TaskMethodReturn("Task 4")).Result;
            //Console.WriteLine($"Task 4 Result is:{result4}");
            #endregion


            #region 测试Task线程是来自于ThreadPool

            // Test();
            #endregion

            // 合作开发项目,每个人负责一个模块,可以认为是多线程
            // 无序
            //Console.WriteLine("开始合作开发一个大项目!");
            //Task.Run(() => CodingShow("Tom", "搭建微服务架构!"));
            //Task.Run(() => CodingShow("Kevin", "微信接口!"));
            //Task.Run(() => CodingShow("Jack", "搭建后台框架!"));
            //Task.Run(() => CodingShow("Alex", "设计数据库!"));
            //Task.Run(() => CodingShow("Lee", "支付宝接口对接!"));
            //Console.WriteLine("所有模块都开发完成,开始搭建测试环境");

            #region WaitAll
            //// 定义一个Task类型的集合
            //List<Task> taskList = new List<Task>();
            //Console.WriteLine("开始合作开发一个大项目!");
            //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服务架构!")));
            //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
            //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后台框架!")));
            //taskList.Add(Task.Run(() => CodingShow("Alex", "设计数据库!")));
            //taskList.Add(Task.Run(() => CodingShow("Lee", "支付宝接口对接!")));

            //// 等待所有模块都开发完成,才能搭建测试环境
            //Task.WaitAll(taskList.ToArray());
            //Console.WriteLine("所有模块都开发完成,开始搭建测试环境");
            #endregion

            #region WaitAny
            // 定义一个Task类型的集合
            //List<Task> taskList = new List<Task>();
            //Console.WriteLine("开始合作开发一个大项目!");
            //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服务架构!")));
            //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
            //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后台框架!")));
            //taskList.Add(Task.Run(() => CodingShow("Alex", "设计数据库!")));
            //taskList.Add(Task.Run(() => CodingShow("Lee", "支付宝接口对接!")));

            //// 等待所有模块都开发完成,才能搭建测试环境
            //Task.WaitAny(taskList.ToArray());
            //Console.WriteLine("有模块开发完成,开始搭建测试环境");
            #endregion

            #region ContinueWhenAll
            //List<Task> taskList = new List<Task>();
            //Console.WriteLine("开始合作开发一个大项目!");
            //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服务架构!")));
            //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
            //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后台框架!")));
            //taskList.Add(Task.Run(() => CodingShow("Alex", "设计数据库!")));
            //taskList.Add(Task.Run(() => CodingShow("Lee", "支付宝接口对接!")));
            //TaskFactory factory = new TaskFactory();
            //factory.ContinueWhenAll(taskList.ToArray(), t => Console.WriteLine("所有模块开发完成"));
            #endregion

            #region ContinueWhenAll
            //List<Task> taskList = new List<Task>();
            //Console.WriteLine("开始合作开发一个大项目!");
            //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服务架构!")));
            //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
            //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后台框架!")));
            //taskList.Add(Task.Run(() => CodingShow("Alex", "设计数据库!")));
            //taskList.Add(Task.Run(() => CodingShow("Lee", "支付宝接口对接!")));
            //TaskFactory factory = new TaskFactory();
            //factory.ContinueWhenAny(taskList.ToArray(), t => Console.WriteLine("某一个模块开发完成"));
            #endregion

            #region ContinueWith
            Task.Run(() => { Console.WriteLine("任务执行完成"); }).ContinueWith(p=> 
            {
               Task.Run(() => { Console.WriteLine("执行回调"); });
            });
            #endregion



            Console.ReadKey();
        }

        /// <summary>
        /// 返回一个Task<int>
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        static Task<int> CreateTask(string name)
        {
            // 参数是Func<int>
            return new Task<int>(() => TaskMethodReturn(name));
        }

        static void TaskMethod(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
        }

        static int TaskMethodReturn(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                   name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            return 42;
        }

        /// <summary>
        /// 测试Task的线程来自于ThreadPool
        /// </summary>
        static void Test()
        {
            // 设置线程池中最大的线程数
            ThreadPool.SetMaxThreads(6, 6);
            // 创建Task的集合
            List<Task> taskList = new List<Task>();
            // 创建int类型的集合,用于存放线程ID
            List<int> threadIdList = new List<int>();
            // 使用Task循环创建50个线程
            for (int i = 0; i < 30; i++)
            {
                int k = i;
                Task task = Task.Run(() =>
                {
                    // 当前线程ID加入到集合中
                    threadIdList.Add(Thread.CurrentThread.ManagedThreadId);
                    Console.WriteLine($"this is {k} 循环 ThreadID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
                    // 休眠
                    Thread.Sleep(200);
                });
                // 把task加入到集合中
                taskList.Add(task);
            }

            // 等待所有的线程执行完
            Task.WaitAll(taskList.ToArray());
            // 输出总数量
            Console.WriteLine($"线程总数:{threadIdList.Distinct().Count()}");
        }

        /// <summary>
        /// 模拟Coding过程
        /// </summary>
        /// <param name="name"></param>
        /// <param name="projectName"></param>
        static void CodingShow(string name, string projectName)
        {
            Console.WriteLine($"CodingShow Start  {name} {projectName}  {Thread.CurrentThread.ManagedThreadId.ToString("00")} ");
            long lResult = 0;
            for (int i = 0; i < 1_000_000_000; i++)
            {
                lResult += i;
            }

            Console.WriteLine($"CodingShow   End  {name} {projectName} {Thread.CurrentThread.ManagedThreadId.ToString("00")} ");
        }
    }
}

到此这篇关于C#多线程编程Task用法的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: C#多线程编程Task用法详解

本文链接: https://www.lsjlt.com/news/143189.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C#多线程编程Task用法详解
    目录一、基本概念Task优势二、Task用法创建任务1、使用Task创建无返回值2、使用Task.Run方法创建任务3、使用Factory方式创建任务4、创建带返回值的Task三、常...
    99+
    2024-04-02
  • C#多线程编程Task如何使用
    这篇“C#多线程编程Task如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C#多线程编程Task如何使用”文章吧。一...
    99+
    2023-06-29
  • C++多线程编程详解
    目录C++多线程1. 概念1.1 概念2. 常用API1.thread2.互斥锁mutex3. 挂起和唤醒3. 应用场景3.1 call_once执行一次的函数3.2 conditi...
    99+
    2024-04-02
  • C++多线程编程超详解
    目录C++多线程1. 概念2. 常用API1.thread2.互斥锁mutex3. 挂起和唤醒3. 应用场景3.1 call_once执行一次的函数3.2 condition_var...
    99+
    2024-04-02
  • C#多线程用法详解
    目录一、基本概念1、进程2、线程二、多线程2.1System.Threading.Thread类2.2线程的常用属性2.2.1线程的标识符2.2.2线程的优先级别2.2.3线程的状态...
    99+
    2024-04-02
  • 详解C语言编程之thread多线程
    目录线程创建与结束线程的创建方式:线程的结束方式:join()detach()互斥锁<mutex> 头文件介绍std::mutex 介绍std::lock_guardst...
    99+
    2024-04-02
  • C#多线程之线程池ThreadPool详解
    一、ThreadPool概述 提供一个线程池,该线程池可用于执行任务、发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。 创建线程需要时间。如果有不同的小任务要完成,就可...
    99+
    2024-04-02
  • C#多线程之任务的用法详解
    目录一.启动任务1.使用线程池的任务2.同步任务3.使用单独线程的任务二.任务的结果————Future三.连续的任务四.任务的层次结...
    99+
    2024-04-02
  • 如何在C#项目中使用Task实现并行和多线程编程
    这期内容当中小编将会给大家带来有关如何在C#项目中使用Task实现并行和多线程编程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。任务和线程的区别:任务是架构在线程之上的,也就是说任务最终还是要抛给线程去执...
    99+
    2023-06-06
  • C#并行编程Task类用法介绍
    Task和ThreadPool的功能类似,可以用来创建一些轻量级的并行任务。对于将一个任务放进线程池 ThreadPool.QueueUserWorkItem(A); 这段代码用Ta...
    99+
    2024-04-02
  • C#中Thread(线程)和Task(任务)实例详解
    目录线程一,使用Thread类启动线程和数据传输二,线程池ThreadPool类任务一,创建并启动任务二,连续任务三,资源冲突问题 总结线程 线程:对于所有需要等待的操作,...
    99+
    2024-04-02
  • Kotlinserver多线程编程详细讲解
    目录service 是什么多线程编程Service 基本用法service 是什么 Service是实现程序后台运行的解决方案,适合执行非交互,后台预先的任务,即使用户打开其他应用,...
    99+
    2023-01-30
    Kotlin server多线程编程 Kotlin server Kotlin多线程编程
  • Java多线程编程详细解释
    目录一、多线程的优缺点多线程的优点:多线程的代价:二、创建java多线程1、创建Thread的子类2、实现Runnable接口三、线程安全四、java同步块五、java线程通信六、j...
    99+
    2024-04-02
  • Python多线程编程入门详解
    目录一、任务、进程和线程任务进程线程进程和线程的关系二、Python既支持多进程,又支持多线程Python实现多进程Process进程类的说明Python实现多线程线程类Thread...
    99+
    2024-04-02
  • C++ 多线程编程中线程池的应用
    c++++ 多线程编程中使用线程池的好处包括:1)减少线程创建次数;2)负载均衡;3)避免资源争用。例如,通过使用线程池将图像转换任务分配给线程池,可以提高文件转换应用程序的转换速度。 ...
    99+
    2024-05-14
    多线程 线程池 c++ 标准库
  • C# 多线程详细讲解
    多线程是指在一个程序中同时执行多个线程,每个线程可以独立执行不同的任务。在 C# 中,可以使用 System.Threading 命...
    99+
    2023-09-09
    C#
  • C#多线程之线程池ThreadPool用法
    目录一、ThreadPool1、QueueUserWorkItem()2、GetMaxThreads()3、GetMinThreads()4、SetMaxThreads()和SetM...
    99+
    2024-04-02
  • C#多线程系列之async和await用法详解
    目录async和awaitasyncawait从以往知识推导创建异步任务创建异步任务并返回Task异步改同步说说 await Task说说 async Task<TR...
    99+
    2024-04-02
  • C#多线程Thread使用示例详解
    本文实例为大家分享了C#多线程Thread使用的示例代码,供大家参考,具体内容如下 多线程: 线程生命周期状态图: C#线程优先级(概率高低): 基本使用示例: usin...
    99+
    2024-04-02
  • Java多线程编程综合案例详解
    目录Java多线程综合案例数字加减生产电脑竞争抢答Java多线程综合案例 数字加减 设计4个线程对象,两个线程执行减操作,两个线程执行加操作 public class ThreadD...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作