最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#多線程編程Task用法詳解

 更新時間:2022年03月20日 15:07:58   作者:.NET開發(fā)菜鳥  
本文詳細講解了C#多線程編程Task的用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一、基本概念

Task優(yōu)勢

ThreadPool相比Thread來說具備了很多優(yōu)勢,但是ThreadPool卻又存在一些使用上的不方便,例如:

  • ThreadPool不支持線程的取消、完成、失敗通知等交互性操作;
  • ThreadPool不支持線程執(zhí)行的先后次序;

.NET Framework 在4.0的時候提供了一個功能更強大的概念:Task。Task在ThreadPool的基礎上進行了優(yōu)化,并提供了更多的API??聪旅嬉粋€簡單的示例:

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

namespace TaskDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 創(chuàng)建Task
            Task t = new Task(() => 
            {
                Console.WriteLine("任務開始工作.....");
                Thread.Sleep(5000);
            });
            // 啟動
            t.Start();
            t.ContinueWith((task) => 
            {
                Console.WriteLine("任務完成,完成時候的狀態(tài)為:");
                Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted);
            });
            Console.WriteLine("啟動");
            Console.ReadKey();
        }
    }
}

二、Task用法

創(chuàng)建任務

Task創(chuàng)建的任務可以分為有返回值和無返回值兩種。

1、使用Task創(chuàng)建無返回值

先看一下Task的定義:

可以看到Task構造函數(shù)的參數(shù)是Action委托。所以使用Task創(chuàng)建任務的代碼如下:

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

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

            #region 1、使用Task創(chuàng)建任務
            Task task = new Task(() => TaskMethod("Task 1"));
            Console.WriteLine("before start status:"+task.Status);
            // Task創(chuàng)建的任務必須調(diào)用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);
        }
    }
}

程序運行結果:

注:任務的狀態(tài),Start之前為Created,Start之后為WaitingToRun。

2、使用Task.Run方法創(chuàng)建任務

Task.Run創(chuàng)建的任務可以執(zhí)行啟動:

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

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

            #region 1、使用Task創(chuàng)建任務
            //Task task = new Task(() => TaskMethod("Task 1"));
            //Console.WriteLine("before start status:"+task.Status);
            //// Task創(chuàng)建的任務必須調(diào)用start方法才能啟動
            //task.Start();
            //Console.WriteLine("after start status:" + task.Status);
            #endregion

            #region 2、使用Task.Run創(chuàng)建任務
            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方式創(chuàng)建任務

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

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

            #region 1、使用Task創(chuàng)建任務
            //Task task = new Task(() => TaskMethod("Task 1"));
            //Console.WriteLine("before start status:"+task.Status);
            //// Task創(chuàng)建的任務必須調(diào)用start方法才能啟動
            //task.Start();
            //Console.WriteLine("after start status:" + task.Status);
            #endregion

            #region 2、使用Task.Run創(chuàng)建任務
            // Task.Run(() => TaskMethod("Task Run"));
            #endregion

            #region 3、使用Factory創(chuàng)建任務
            // 使用Task.Factory創(chuàng)建
            Task.Factory.StartNew(() => TaskMethod("Task 4"));
            //標記為長時間運行任務,則任務不會使用線程池,而在單獨的線程中運行。
            Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);

            // 實例化TaskFactory對象,然后創(chuàng)建
            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、創(chuàng)建帶返回值的Task

代碼如下:

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

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

            #region 1、使用Task創(chuàng)建任務
            //Task task = new Task(() => TaskMethod("Task 1"));
            //Console.WriteLine("before start status:"+task.Status);
            //// Task創(chuàng)建的任務必須調(diào)用start方法才能啟動
            //task.Start();
            //Console.WriteLine("after start status:" + task.Status);
            #endregion

            #region 2、使用Task.Run創(chuàng)建任務
            // Task.Run(() => TaskMethod("Task Run"));
            #endregion

            #region 3、使用Task.Factory創(chuàng)建任務
            //Task.Factory.StartNew(() => TaskMethod("Task 4"));
            ////標記為長時間運行任務,則任務不會使用線程池,而在單獨的線程中運行。
            //Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);
            #endregion

            #region 4、創(chuàng)建帶返回值的任務
            TaskMethodReturn("Main Thread Task");
            // 創(chuàng)建帶返回值的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)
        {
            // 參數(shù)是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()
{
            // 設置線程池中最大的線程數(shù)
            ThreadPool.SetMaxThreads(6, 6);
            // 創(chuàng)建Task的集合
            List<Task> taskList = new List<Task>();
            // 創(chuàng)建int類型的集合,用于存放線程ID
            List<int> threadIdList = new List<int>();
            // 使用Task循環(huán)創(chuàng)建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} 循環(huán) ThreadID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
                    // 休眠
                    Thread.Sleep(200);
                });
                // 把task加入到集合中
                taskList.Add(task);
            }

            // 等待所有的線程執(zhí)行完
            Task.WaitAll(taskList.ToArray());
            // 輸出總數(shù)量
            Console.WriteLine($"線程總數(shù):{threadIdList.Distinct().Count()}");
}

程序運行結果:

從結果中可以看出,Task中的線程確實是來自于ThreadPool。

三、常見方法

我們以下面的一個例子來講解Task中比較常見的幾個方法。多名開發(fā)者合作開發(fā)一個項目,每個人負責一個模塊的開發(fā),我們可以把這個過程認為是多線程,代碼如下:

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創(chuàng)建任務
            //Task task = new Task(() => TaskMethod("Task 1"));
            //Console.WriteLine("before start status:"+task.Status);
            //// Task創(chuàng)建的任務必須調(diào)用start方法才能啟動
            //task.Start();
            //Console.WriteLine("after start status:" + task.Status);
            #endregion

            #region 2、使用Task.Run創(chuàng)建任務
            // Task.Run(() => TaskMethod("Task Run"));
            #endregion

            #region 3、使用Factory創(chuàng)建任務
            // 使用Task.Factory創(chuàng)建
            //Task.Factory.StartNew(() => TaskMethod("Task 4"));
            ////標記為長時間運行任務,則任務不會使用線程池,而在單獨的線程中運行。
            //Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);

            // 實例化TaskFactory對象,然后創(chuàng)建
            //TaskFactory factory = new TaskFactory();
            //factory.StartNew(() => TaskMethod("Task 6"));
            #endregion

            #region 4、創(chuàng)建帶返回值的任務
            //TaskMethodReturn("Main Thread Task");
            //// 創(chuàng)建帶返回值的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

            // 合作開發(fā)項目,每個人負責一個模塊,可以認為是多線程
            Console.WriteLine("開始合作開發(fā)一個大項目!");
            Task.Run(() => CodingShow("Tom", "搭建微服務架構!"));
            Task.Run(() => CodingShow("Kevin", "微信接口!"));
            Task.Run(() => CodingShow("Jack", "搭建后臺框架!"));
            Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!"));
            Task.Run(() => CodingShow("Lee", "支付寶接口對接!"));





            Console.ReadKey();
        }

        /// <summary>
        /// 返回一個Task<int>
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        static Task<int> CreateTask(string name)
        {
            // 參數(shù)是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()
        {
            // 設置線程池中最大的線程數(shù)
            ThreadPool.SetMaxThreads(6, 6);
            // 創(chuàng)建Task的集合
            List<Task> taskList = new List<Task>();
            // 創(chuàng)建int類型的集合,用于存放線程ID
            List<int> threadIdList = new List<int>();
            // 使用Task循環(huán)創(chuàng)建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} 循環(huán) ThreadID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
                    // 休眠
                    Thread.Sleep(200);
                });
                // 把task加入到集合中
                taskList.Add(task);
            }

            // 等待所有的線程執(zhí)行完
            Task.WaitAll(taskList.ToArray());
            // 輸出總數(shù)量
            Console.WriteLine($"線程總數(shù):{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")} ");
        }
    }
}

程序運行結果:

這時需求發(fā)生了變化,所有的模塊都開發(fā)完成以后,開始搭建測試環(huán)境,修改代碼如下:

// 合作開發(fā)項目,每個人負責一個模塊,可以認為是多線程
Console.WriteLine("開始合作開發(fā)一個大項目!");
Task.Run(() => CodingShow("Tom", "搭建微服務架構!"));
Task.Run(() => CodingShow("Kevin", "微信接口!"));
Task.Run(() => CodingShow("Jack", "搭建后臺框架!"));
Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!"));
Task.Run(() => CodingShow("Lee", "支付寶接口對接!"));
Console.WriteLine("所有模塊都開發(fā)完成,開始搭建測試環(huán)境");

程序運行結果:

可以看到顯然不是我們想要的結果,模塊開發(fā)工作還沒有結束就搭建測試環(huán)境,即子線程還沒有結束,主線程就已經(jīng)結束了。要想實現(xiàn)我們想要的效果,那么必須使主線程等待所有子線程都結束以后,主線程才能結束。

1、WaitAll()

WaitAll()表示等待所有的Task都執(zhí)行完成??碬aitAll()的定義:

WaitAll()方法有很多重載,我們在這里使用第一個重載方法,即參數(shù)是Task[]數(shù)組。查看Run()方法的定義時,我們會發(fā)現(xiàn)Run()方法的返回值就是Task類型,我們使用WaitAll()修改上面的代碼:

// 定義一個Task類型的集合
List<Task> taskList = new List<Task>();
Console.WriteLine("開始合作開發(fā)一個大項目!");
taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!")));
taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后臺框架!")));
taskList.Add(Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!")));
taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶接口對接!")));

// 等待所有模塊都開發(fā)完成,才能搭建測試環(huán)境
Task.WaitAll(taskList.ToArray());
Console.WriteLine("所有模塊都開發(fā)完成,開始搭建測試環(huán)境");

程序運行結果:

WaitAll()會使程序產(chǎn)生卡頓。

加載首頁信息的時候可以使用WaitAll()方法。一個首頁信息可能來自于幾部分的數(shù)據(jù),每一部分的數(shù)據(jù)對應一個線程,只有所有的線程都執(zhí)行完畢才顯示首頁信息。

2、WaitAny()

這時需求又發(fā)生改變了:某一個模塊開發(fā)完成以后就搭建測試環(huán)境。這時候就可以使用WaitAny()了。WaitAny()表示等待其中任何一個任務完成就會進入下一個任務,定義如下:

修改后的代碼如下:

// 定義一個Task類型的集合
List<Task> taskList = new List<Task>();
Console.WriteLine("開始合作開發(fā)一個大項目!");
taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!")));
taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后臺框架!")));
taskList.Add(Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!")));
taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶接口對接!")));

// 等待所有模塊都開發(fā)完成,才能搭建測試環(huán)境
Task.WaitAny(taskList.ToArray());
Console.WriteLine("有模塊開發(fā)完成,開始搭建測試環(huán)境");

程序運行結果:

可以看到:設計數(shù)據(jù)庫模塊完成以后,就開始搭建測試環(huán)境了。如何需求。

WaitAny()會使程序產(chǎn)生卡頓。

有一個列表數(shù)據(jù),數(shù)據(jù)可以來源于接口、緩存、數(shù)據(jù)庫等,可以開啟多個線程,只要有一個線程執(zhí)行完畢就可以繼續(xù)執(zhí)行下面的步驟,這時就可以使用WaitAny()。

3、ContinueWhenAll()

WaitAll()會卡頓界面,那么有沒有不卡頓界面的呢?ContinueWhenAll和WaitAll實現(xiàn)的效果一樣,代碼如下:

List<Task> taskList = new List<Task>();
Console.WriteLine("開始合作開發(fā)一個大項目!");
taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!")));
taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后臺框架!")));
taskList.Add(Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!")));
taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶接口對接!")));
TaskFactory factory = new TaskFactory();
factory.ContinueWhenAll(taskList.ToArray(), t => Console.WriteLine("所有模塊開發(fā)完成"));

程序運行結果:

4、ContinueWhenAny

ContinueWhenAny實現(xiàn)的效果和WaitAny一樣,ContinueWhenAny不會卡頓界面,代碼如下:

List<Task> taskList = new List<Task>();
Console.WriteLine("開始合作開發(fā)一個大項目!");
taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!")));
taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后臺框架!")));
taskList.Add(Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!")));
taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶接口對接!")));
TaskFactory factory = new TaskFactory();
factory.ContinueWhenAny(taskList.ToArray(), t => Console.WriteLine("某一個模塊開發(fā)完成"));

程序運行結果:

ContinueWhenAll()和ContinueWhenAny()都會開啟一個新的線程。

5、ContinueWith

ContinueWith表示回調(diào),代碼如下:

Task.Run(() => { Console.WriteLine("任務執(zhí)行完成"); }).ContinueWith(p=> 
{
      Task.Run(() => { Console.WriteLine("執(zhí)行回調(diào)"); });
});

程序執(zhí)行結果:

程序完整代碼如下:

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創(chuàng)建任務
            //Task task = new Task(() => TaskMethod("Task 1"));
            //Console.WriteLine("before start status:"+task.Status);
            //// Task創(chuàng)建的任務必須調(diào)用start方法才能啟動
            //task.Start();
            //Console.WriteLine("after start status:" + task.Status);
            #endregion

            #region 2、使用Task.Run創(chuàng)建任務
            // Task.Run(() => TaskMethod("Task Run"));
            #endregion

            #region 3、使用Factory創(chuàng)建任務
            // 使用Task.Factory創(chuàng)建
            //Task.Factory.StartNew(() => TaskMethod("Task 4"));
            ////標記為長時間運行任務,則任務不會使用線程池,而在單獨的線程中運行。
            //Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);

            // 實例化TaskFactory對象,然后創(chuàng)建
            //TaskFactory factory = new TaskFactory();
            //factory.StartNew(() => TaskMethod("Task 6"));
            #endregion

            #region 4、創(chuàng)建帶返回值的任務
            //TaskMethodReturn("Main Thread Task");
            //// 創(chuàng)建帶返回值的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

            // 合作開發(fā)項目,每個人負責一個模塊,可以認為是多線程
            // 無序
            //Console.WriteLine("開始合作開發(fā)一個大項目!");
            //Task.Run(() => CodingShow("Tom", "搭建微服務架構!"));
            //Task.Run(() => CodingShow("Kevin", "微信接口!"));
            //Task.Run(() => CodingShow("Jack", "搭建后臺框架!"));
            //Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!"));
            //Task.Run(() => CodingShow("Lee", "支付寶接口對接!"));
            //Console.WriteLine("所有模塊都開發(fā)完成,開始搭建測試環(huán)境");

            #region WaitAll
            //// 定義一個Task類型的集合
            //List<Task> taskList = new List<Task>();
            //Console.WriteLine("開始合作開發(fā)一個大項目!");
            //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!")));
            //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
            //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后臺框架!")));
            //taskList.Add(Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!")));
            //taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶接口對接!")));

            //// 等待所有模塊都開發(fā)完成,才能搭建測試環(huán)境
            //Task.WaitAll(taskList.ToArray());
            //Console.WriteLine("所有模塊都開發(fā)完成,開始搭建測試環(huán)境");
            #endregion

            #region WaitAny
            // 定義一個Task類型的集合
            //List<Task> taskList = new List<Task>();
            //Console.WriteLine("開始合作開發(fā)一個大項目!");
            //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!")));
            //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
            //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后臺框架!")));
            //taskList.Add(Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!")));
            //taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶接口對接!")));

            //// 等待所有模塊都開發(fā)完成,才能搭建測試環(huán)境
            //Task.WaitAny(taskList.ToArray());
            //Console.WriteLine("有模塊開發(fā)完成,開始搭建測試環(huán)境");
            #endregion

            #region ContinueWhenAll
            //List<Task> taskList = new List<Task>();
            //Console.WriteLine("開始合作開發(fā)一個大項目!");
            //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!")));
            //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
            //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后臺框架!")));
            //taskList.Add(Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!")));
            //taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶接口對接!")));
            //TaskFactory factory = new TaskFactory();
            //factory.ContinueWhenAll(taskList.ToArray(), t => Console.WriteLine("所有模塊開發(fā)完成"));
            #endregion

            #region ContinueWhenAll
            //List<Task> taskList = new List<Task>();
            //Console.WriteLine("開始合作開發(fā)一個大項目!");
            //taskList.Add(Task.Run(() => CodingShow("Tom", "搭建微服務架構!")));
            //taskList.Add(Task.Run(() => CodingShow("Kevin", "微信接口!")));
            //taskList.Add(Task.Run(() => CodingShow("Jack", "搭建后臺框架!")));
            //taskList.Add(Task.Run(() => CodingShow("Alex", "設計數(shù)據(jù)庫!")));
            //taskList.Add(Task.Run(() => CodingShow("Lee", "支付寶接口對接!")));
            //TaskFactory factory = new TaskFactory();
            //factory.ContinueWhenAny(taskList.ToArray(), t => Console.WriteLine("某一個模塊開發(fā)完成"));
            #endregion

            #region ContinueWith
            Task.Run(() => { Console.WriteLine("任務執(zhí)行完成"); }).ContinueWith(p=> 
            {
               Task.Run(() => { Console.WriteLine("執(zhí)行回調(diào)"); });
            });
            #endregion



            Console.ReadKey();
        }

        /// <summary>
        /// 返回一個Task<int>
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        static Task<int> CreateTask(string name)
        {
            // 參數(shù)是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()
        {
            // 設置線程池中最大的線程數(shù)
            ThreadPool.SetMaxThreads(6, 6);
            // 創(chuàng)建Task的集合
            List<Task> taskList = new List<Task>();
            // 創(chuàng)建int類型的集合,用于存放線程ID
            List<int> threadIdList = new List<int>();
            // 使用Task循環(huán)創(chuàng)建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} 循環(huán) ThreadID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}");
                    // 休眠
                    Thread.Sleep(200);
                });
                // 把task加入到集合中
                taskList.Add(task);
            }

            // 等待所有的線程執(zhí)行完
            Task.WaitAll(taskList.ToArray());
            // 輸出總數(shù)量
            Console.WriteLine($"線程總數(shù):{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用法的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • c#實現(xiàn)winform屏幕截圖并保存的示例

    c#實現(xiàn)winform屏幕截圖并保存的示例

    這篇文章主要介紹了c#實現(xiàn)winform屏幕截圖并保存的示例,需要的朋友可以參考下
    2014-02-02
  • C#開發(fā)Windows UWP系列之對話框MessageDialog和ContentDialog

    C#開發(fā)Windows UWP系列之對話框MessageDialog和ContentDialog

    這篇文章介紹了C#開發(fā)Windows UWP系列之對話框MessageDialog和ContentDialog,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C#生成單頁靜態(tài)頁簡單實例

    C#生成單頁靜態(tài)頁簡單實例

    這篇文章主要介紹了C#生成單頁靜態(tài)頁簡單實例,是一個非常實用的技巧,需要的朋友可以參考下
    2014-10-10
  • C#中的委托和事件

    C#中的委托和事件

    這篇文章介紹了C#中的委托和事件,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • Oracle中for循環(huán)的使用方法

    Oracle中for循環(huán)的使用方法

    這篇文章介紹了Oracle中for循環(huán)的使用方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • C#自定義鼠標拖拽Drag&Drop效果之基本原理及基本實現(xiàn)代碼

    C#自定義鼠標拖拽Drag&Drop效果之基本原理及基本實現(xiàn)代碼

    拖拽效果無論是在系統(tǒng)上、應用上、還是在網(wǎng)頁上,拖拽隨處可見,下面通過本文介紹下C#自定義鼠標拖拽Drag&Drop效果之基本原理及基本實現(xiàn)代碼,需要的朋友可以參考下
    2022-04-04
  • C#面向對象編程中依賴反轉原則的示例詳解

    C#面向對象編程中依賴反轉原則的示例詳解

    在面向對象編程中,SOLID?是五個設計原則的首字母縮寫,旨在使軟件設計更易于理解、靈活和可維護。本文將通過實例詳細講講C#面向對象編程中依賴反轉原則,需要的可以參考一下
    2022-07-07
  • C#避免類型轉換異常的三種方法

    C#避免類型轉換異常的三種方法

    在 C# 中,可以通過使用類型轉換操作符或者類型轉換方法來進行類型轉換,但是在進行類型轉換時,可能會出現(xiàn)類型轉換異常,為了避免這種異常的發(fā)生,本文給大家介紹了幾種方法,感興趣的朋友可以參考一下
    2024-04-04
  • C# 中GUID生成格式的四種方法

    C# 中GUID生成格式的四種方法

    這篇文章主要介紹了C# 中GUID生成格式的四種方法,需要的朋友可以參考下
    2017-02-02
  • C# 類的聲明詳解

    C# 類的聲明詳解

    本文主要對C# 類的聲明進行詳細介紹。具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01

最新評論

涞源县| 台东县| 本溪| 泸州市| 克东县| 天台县| 沂南县| 邢台市| 沽源县| 山阳县| 清水河县| 察隅县| 长治县| 印江| 凉山| 顺昌县| 安达市| 山东| 白水县| 肃宁县| 衢州市| 望都县| 江北区| 古浪县| 措勤县| 灌云县| 同德县| 仁怀市| 娄底市| 南岸区| 沈阳市| 五家渠市| 武平县| 自治县| 大方县| 丹江口市| 桂阳县| 东乌珠穆沁旗| 咸阳市| 洪湖市| 延川县|