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

c#中task與thread的區(qū)別及使用講解

 更新時間:2022年06月09日 11:04:16   作者:looper.zhuo  
這篇文章主要介紹了c#中task與thread的區(qū)別及使用講解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

一.什么是thread

當我們提及多線程的時候會想到thread和threadpool,這都是異步操作,threadpool其實就是thread的集合,具有很多優(yōu)勢,不過在任務多的時候全局隊列會存在競爭而消耗資源。

thread默認為前臺線程,主程序必須等線程跑完才會關閉,而threadpool相反。

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

二.什么是task

task簡單地看就是任務,那和thread有什么區(qū)別呢?

Task的背后的實現(xiàn)也是使用了線程池線程,但它的性能優(yōu)于ThreadPoll,因為它使用的不是線程池的全局隊列,而是使用的本地隊列,使線程之間的資源競爭減少。

同時Task提供了豐富的API來管理線程、控制。

但是相對前面的兩種耗內(nèi)存,Task依賴于CPU對于多核的CPU性能遠超前兩者,單核的CPU三者的性能沒什么差別。

三.創(chuàng)建一個task任務有兩種模式

1.使用factory創(chuàng)建會直接執(zhí)行

使用new創(chuàng)建不會執(zhí)行,必須等到start啟動之后才執(zhí)行。

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

輸出結(jié)果:

Created
task start
Running
Running
RanToCompletion
RanToCompletion

可以看出task確實是異步執(zhí)行,并且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()執(zhí)行任意一個task就往下繼續(xù)執(zhí)行。

4.task的回調(diào)執(zhí)行

  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的取消

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

var tokenSource = new CancellationTokenSource();//創(chuàng)建取消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);

輸出結(jié)果:

Created
task is to cancel
Canceled

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

  var tokenSource = new CancellationTokenSource();//創(chuàng)建取消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);
            }

輸出結(jié)果:

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

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

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

此時為普通關聯(lián),父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關聯(lián),wait會一直等待父子task執(zhí)行完。

6.task死鎖的問題

我們可以設置最大等待時間,如果超過了等待時間,就不再等待,下面我們來修改代碼,設置最大等待時間為5秒(項目中可以根據(jù)實際情況設置),如果超過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);

輸出結(jié)果:

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

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

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

最后看看threadpoll和task的結(jié)構(gòu)圖:

threadpool:

 task:

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • C#如何遍歷Dictionary

    C#如何遍歷Dictionary

    這篇文章主要為大家詳細介紹了C#遍歷Dictionary的方法,.NET中的Dictionary是鍵/值對的集合,使用起來比較方便,Dictionary也可以用KeyValuePair來迭代遍歷,感興趣的小伙伴們可以參考一下
    2016-04-04
  • Unity 從Resources中動態(tài)加載Sprite圖片的操作

    Unity 從Resources中動態(tài)加載Sprite圖片的操作

    這篇文章主要介紹了Unity 從Resources中動態(tài)加載Sprite圖片的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Unity UI或3D場景實現(xiàn)跟隨手機陀螺儀的晃動效果

    Unity UI或3D場景實現(xiàn)跟隨手機陀螺儀的晃動效果

    這篇文章主要介紹了Unity UI或3D場景實現(xiàn)跟隨手機陀螺儀的晃動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • gridview的buttonfield獲取該行的索引值(實例講解)

    gridview的buttonfield獲取該行的索引值(實例講解)

    本篇文章主要介紹了gridview的buttonfield獲取該行的索引值(實例講解)需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • 如何用WindowsForm給窗口添加一些簡單的動畫效果

    如何用WindowsForm給窗口添加一些簡單的動畫效果

    這篇文章主要介紹了如何用WindowsForm給窗口添加一些簡單的動畫效果,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • 使用C#實現(xiàn)替換文件中的IP地址

    使用C#實現(xiàn)替換文件中的IP地址

    這篇文章主要為大家詳細介紹了如何使用C#來處理一個實際的編程挑戰(zhàn):讀取一個配置文件并替換其中的IP地址,感興趣的小伙伴可以了解下
    2024-01-01
  • C#編程自學之數(shù)據(jù)類型和變量一

    C#編程自學之數(shù)據(jù)類型和變量一

    本節(jié)課我們將學習C#編程語言的數(shù)據(jù)類型,數(shù)據(jù)類型可以分為值類型和引用類型,接著介紹變量的使用方法和作用域等內(nèi)容,為了方便大家理解,我們還會舉一些小例子作為說明。
    2015-10-10
  • 詳解C# Lazy Loading(延遲加載)

    詳解C# Lazy Loading(延遲加載)

    這篇文章主要介紹了C# Lazy Loading(延遲加載)的相關資料,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下
    2021-04-04
  • C#中使用Cache框架快速實現(xiàn)Cache操作

    C#中使用Cache框架快速實現(xiàn)Cache操作

    這篇文章介紹了C#中使用Cache框架快速實現(xiàn)Cache操作的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • 詳解C#中HashTable的用法

    詳解C#中HashTable的用法

    在.NET Framework中,Hashtable是System.Collections命名空間提供的一個容器,用于處理和表現(xiàn)類似keyvalue的鍵值對,其中key通??捎脕砜焖俨檎?,同時key是區(qū)分大小寫;value用于存儲對應于key的值
    2016-02-02

最新評論

南康市| 枣强县| 沙雅县| 蓬莱市| 乐业县| 丹棱县| 得荣县| 微山县| 黑水县| 蓬莱市| 高阳县| 南江县| 长春市| 新巴尔虎左旗| 七台河市| 衢州市| 嘉善县| 玉溪市| 丰镇市| 晋宁县| 西城区| 临桂县| 仁布县| 启东市| 平顶山市| 平乡县| 怀远县| 共和县| 大连市| 新宁县| 平邑县| 海口市| 岳阳县| 元朗区| 墨玉县| 隆子县| 浪卡子县| 革吉县| 温州市| 同江市| 武山县|