中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#多線程編程Task如何使用

發布時間:2022-03-21 09:11:22 來源:億速云 閱讀:473 作者:iii 欄目:開發技術

這篇“C#多線程編程Task如何使用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“C#多線程編程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的定義:

C#多線程編程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);
        }
    }
}

程序運行結果:

C#多線程編程Task如何使用

注:任務的狀態,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);
        }
    }
}

程序運行結果:

C#多線程編程Task如何使用

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);
        }
    }
}

程序運行結果:

C#多線程編程Task如何使用

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;
        }
    }
}

程序運行結果:

C#多線程編程Task如何使用

我們在文章開始的時候說過,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()}");
}

程序運行結果:

C#多線程編程Task如何使用

從結果中可以看出,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")} ");
        }
    }
}

程序運行結果:

C#多線程編程Task如何使用

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

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

程序運行結果:

C#多線程編程Task如何使用

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

1、WaitAll()

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

C#多線程編程Task如何使用

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("所有模塊都開發完成,開始搭建測試環境");

程序運行結果:

C#多線程編程Task如何使用

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

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

2、WaitAny()

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

C#多線程編程Task如何使用

修改后的代碼如下:

// 定義一個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("有模塊開發完成,開始搭建測試環境");

程序運行結果:

C#多線程編程Task如何使用

可以看到:設計數據庫模塊完成以后,就開始搭建測試環境了。如何需求。

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("所有模塊開發完成"));

程序運行結果:

C#多線程編程Task如何使用

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("某一個模塊開發完成"));

程序運行結果:

C#多線程編程Task如何使用

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

5、ContinueWith

ContinueWith表示回調,代碼如下:

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

程序執行結果:

C#多線程編程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.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如何使用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南澳县| 天门市| 迭部县| 石棉县| 中宁县| 嵊州市| 蛟河市| 屏边| 仁布县| 阿勒泰市| 洪雅县| 固镇县| 武安市| 西安市| 绥滨县| 南木林县| 通山县| 彭阳县| 邵武市| 博湖县| 济阳县| 莎车县| 长治县| 沂源县| 剑阁县| 留坝县| 盐池县| 陕西省| 萨嘎县| 来宾市| 湖南省| 固镇县| 金湖县| 沛县| 林口县| 龙海市| 珲春市| 安顺市| 石狮市| 上虞市| 石林|