91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

c#中task與thread區別是什么

發布時間:2022-02-14 13:38:38 來源:億速云 閱讀:296 作者:小新 欄目:開發技術

這篇文章主要介紹了c#中task與thread區別是什么,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

1.什么是thread

當我們提及多線程的時候會想到thread和threadpool,這都是異步操作,threadpool其實就是thread的集合,具有很多優勢,不過在任務多的時候全局隊列會存在競爭而消耗資源。thread默認為前臺線程,主程序必須等線程跑完才會關閉,而threadpool相反。

總結:threadpool確實比thread性能優,但是兩者都沒有很好的api區控制,如果線程執行無響應就只能等待結束,從而誕生了task任務。

2.什么是task

 task簡單地看就是任務,那和thread有什么區別呢?Task的背后的實現也是使用了線程池線程,但它的性能優于ThreadPoll,因為它使用的不是線程池的全局隊列,而是使用的本地隊列,使線程之間的資源競爭減少。同時Task提供了豐富的API來管理線程、控制。但是相對前面的兩種耗內存,Task依賴于CPU對于多核的CPU性能遠超前兩者,單核的CPU三者的性能沒什么差別。

3.創建一個task任務有兩種模式:

1.使用factory創建會直接執行,使用new創建不會執行,必須等到start啟動之后才執行。

 public void test()
        {
            var testTask = new Task(() =>
            {
                Console.WriteLine("task start");
            });
            testTask.Start();
            var factoryTeak = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("factory task start");
            });
        }

2.我們來看看task的生命周期

var testTask = new Task(() =>
            {
                Console.WriteLine("task start");
                System.Threading.Thread.Sleep(2000);
            });
            Console.WriteLine(testTask.Status);
            testTask.Start();
            Console.WriteLine(testTask.Status);
            Console.WriteLine(testTask.Status);         
            testTask.Wait();
            Console.WriteLine(testTask.Status);
            Console.WriteLine(testTask.Status);

輸出結果:

Created
task start
Running
Running
RanToCompletion
RanToCompletion

可以看出task確實是異步執行,并且wait很好地控制了task。

3.下面演示幾個控制task的方法

     var testTask = new Task(() =>
            {
                Console.WriteLine("task start");
                System.Threading.Thread.Sleep(2000);
            });
            testTask.Start();
            testTask.Wait();
 var testTask = new Task(() =>
            {
               Console.WriteLine("task start");
               System.Threading.Thread.Sleep(2000);
            });
            testTask.Start();
var factoryTeak = Task.Factory.StartNew(() =>
               {                 
                  Console.WriteLine("factory task start");
               });
              Task.WaitAll(testTask, factoryTeak);
              Console.WriteLine("end");
 var testTask = new Task(() =>
            {
                Console.WriteLine("task start");
                System.Threading.Thread.Sleep(2000);
            });
            testTask.Start();
 var factoryTeak = Task.Factory.StartNew(() =>
               {                  
                  Console.WriteLine("factory task start");
                });
                Task.WaitAny(testTask, factoryTeak);
                Console.WriteLine("end");

通過wait()對單個task進行等待,Task.waitall()對多個task進行等待,waitany()執行任意一個task就往下繼續執行。

4.task的回調執行

  var testTask = new Task(() =>
            {
                Console.WriteLine("task start");
                System.Threading.Thread.Sleep(2000);
            });
            testTask.Start();
            var resultTest = testTask.ContinueWith<string>((Task) => {
                Console.WriteLine("testTask end");
                return "end";
            });
            Console.WriteLine(resultTest.Result);

5.task的取消

首先創建一個取消task的令牌的實例,在不啟動task直接取消:

var tokenSource = new CancellationTokenSource();//創建取消task實例
            var testTask = new Task(() =>
            {
                for (int i = 0; i < 6; i++) {
                    System.Threading.Thread.Sleep(1000);
                }               
            },tokenSource.Token);
            Console.WriteLine(testTask.Status);
            tokenSource.Token.Register(()=> {
                Console.WriteLine("task is to cancel");
            });
            tokenSource.Cancel();
            Console.WriteLine(testTask.Status);

 輸出結果:

Created
task is to cancel
Canceled

如果task啟動了真的取消了task?

  var tokenSource = new CancellationTokenSource();//創建取消task實例
            var testTask = new Task(() =>
            {
                for (int i = 0; i <6; i++) {
                    System.Threading.Thread.Sleep(1000);
                }               
            },tokenSource.Token);
            Console.WriteLine(testTask.Status);
            testTask.Start();
            Console.WriteLine(testTask.Status);
            tokenSource.Token.Register(()=> {
                Console.WriteLine("task is to cancel");
            });
            tokenSource.Cancel();
            Console.WriteLine(testTask.Status);
            for (int i = 0; i < 10; i++)
            {
                System.Threading.Thread.Sleep(1000);
                Console.WriteLine(testTask.Status);
            }

輸出結果:

Created
WaitingToRun
task is to cancel
Running
Running
Running
Running
Running
Running
RanToCompletion
RanToCompletion
RanToCompletion
RanToCompletion
RanToCompletion

 可以看出其實并沒有取消task,此時task還在繼續跑。

6.task的嵌套

  var parentTask = new Task(()=> {
                var childTask = new Task(() =>{
                    System.Threading.Thread.Sleep(2000);
                    Console.WriteLine("childTask to start");
                });
                childTask.Start();
                Console.WriteLine("parentTask to start");
            });
            parentTask.Start();
            parentTask.Wait();
            Console.WriteLine("end");

此時為普通關聯,父task和子task沒影響

  var parentTask = new Task(()=> {
                var childTask = new Task(() =>{
                    System.Threading.Thread.Sleep(2000);
                    Console.WriteLine("childTask to start");
                }, TaskCreationOptions.AttachedToParent);
                childTask.Start();
                Console.WriteLine("parentTask to start");
            } );
            parentTask.Start();
            parentTask.Wait();
            Console.WriteLine("end");

此時為父task和子task關聯,wait會一直等待父子task執行完。

6.task死鎖的問題

我們可以設置最大等待時間,如果超過了等待時間,就不再等待,下面我們來修改代碼,設置最大等待時間為5秒(項目中可以根據實際情況設置),如果超過5秒就輸出哪個任務出錯了

7.對Spinlock的使用

舉例來說Parallel.for和Parallel.foreach是線程不安全的,有可能達不到你的預期,此時就需要加鎖來解決此問題,我們可以加lock和spinlock(自旋鎖)來解決

            SpinLock slock = new SpinLock(false);
            var testLock= new object();
            long sum1 = 0;
            long sum2 = 0;
            long sum3 = 0;
            Parallel.For(0, 100000, i =>
            {
                sum1 += i;
            });
 
            Parallel.For(0, 100000, i =>
            {
                bool lockTaken = false;
                try
                {
                    slock.Enter(ref lockTaken);
                    sum2 += i;
                }
                finally
                {
                    if (lockTaken)
                        slock.Exit(false);
                }
            });
            Parallel.For(0, 100000, i =>
            {
                lock(testLock)
                {
                    sum3 += i;
                };
            });
            Console.WriteLine("Num1的值為:{0}", sum1);
            Console.WriteLine("Num2的值為:{0}", sum2);
            Console.WriteLine("Num3的值為:{0}", sum3);

輸出結果:

Num1的值為:1660913202
Num2的值為:4999950000
Num3的值為:4999950000

Num1的值為:2754493646
Num2的值為:4999950000
Num3的值為:4999950000

Num1的值為:4999950000
Num2的值為:4999950000
Num3的值為:4999950000

最后看看threadpoll和task的結構圖:

threadpool:

c#中task與thread區別是什么

 task:

c#中task與thread區別是什么

感謝你能夠認真閱讀完這篇文章,希望小編分享的“c#中task與thread區別是什么”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

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

AI

阿坝县| 新沂市| 临江市| 五峰| 买车| 旺苍县| 罗田县| 旌德县| 丹东市| 鲁甸县| 淮北市| 博乐市| 潮州市| 凉山| 商河县| 天祝| 汝南县| 南京市| 福泉市| 滦平县| 宁化县| 沂水县| 当雄县| 都兰县| 万荣县| 固阳县| 克什克腾旗| 五原县| 宽城| 宁蒗| 商洛市| 揭阳市| 嘉禾县| 塔河县| 香河县| 泾阳县| 千阳县| 凤台县| 临夏市| 兴化市| 札达县|