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

c#中task與thread區(qū)別及其使用的方法示例

 更新時(shí)間:2022年02月14日 10:23:36   作者:looper.zhuo  
本文主要介紹了c#中task與thread區(qū)別及其使用的方法示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

1.什么是thread

當(dāng)我們提及多線程的時(shí)候會(huì)想到thread和threadpool,這都是異步操作,threadpool其實(shí)就是thread的集合,具有很多優(yōu)勢,不過在任務(wù)多的時(shí)候全局隊(duì)列會(huì)存在競爭而消耗資源。thread默認(rèn)為前臺(tái)線程,主程序必須等線程跑完才會(huì)關(guān)閉,而threadpool相反。

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

2.什么是task

 task簡單地看就是任務(wù),那和thread有什么區(qū)別呢?Task的背后的實(shí)現(xiàn)也是使用了線程池線程,但它的性能優(yōu)于ThreadPoll,因?yàn)樗褂玫牟皇蔷€程池的全局隊(duì)列,而是使用的本地隊(duì)列,使線程之間的資源競爭減少。同時(shí)Task提供了豐富的API來管理線程、控制。但是相對(duì)前面的兩種耗內(nèi)存,Task依賴于CPU對(duì)于多核的CPU性能遠(yuǎn)超前兩者,單核的CPU三者的性能沒什么差別。

3.創(chuàng)建一個(gè)task任務(wù)有兩種模式:

1.使用factory創(chuàng)建會(huì)直接執(zhí)行,使用new創(chuàng)建不會(huì)執(zhí)行,必須等到start啟動(dòng)之后才執(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確實(shí)是異步執(zhí)行,并且wait很好地控制了task。

3.下面演示幾個(gè)控制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()對(duì)單個(gè)task進(jìn)行等待,Task.waitall()對(duì)多個(gè)task進(jìn)行等待,waitany()執(zhí)行任意一個(gè)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)建一個(gè)取消task的令牌的實(shí)例,在不啟動(dòng)task直接取消:

var tokenSource = new CancellationTokenSource();//創(chuàng)建取消task實(shí)例
            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啟動(dòng)了真的取消了task?

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

 可以看出其實(shí)并沒有取消task,此時(shí)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");

此時(shí)為普通關(guān)聯(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");

此時(shí)為父task和子task關(guān)聯(lián),wait會(huì)一直等待父子task執(zhí)行完。

6.task死鎖的問題

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

7.對(duì)Spinlock的使用

舉例來說Parallel.for和Parallel.foreach是線程不安全的,有可能達(dá)不到你的預(yù)期,此時(shí)就需要加鎖來解決此問題,我們可以加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:

 

相關(guān)文章

  • C#常用排序方式總結(jié)

    C#常用排序方式總結(jié)

    在最近的項(xiàng)目中經(jīng)常會(huì)對(duì)C#中的數(shù)據(jù)進(jìn)行排序,對(duì)于基本數(shù)據(jù)類型,其排序方式比較簡單,只需要調(diào)用內(nèi)置算法即可實(shí)現(xiàn),但對(duì)于自定義數(shù)據(jù)類型以及自定義排序規(guī)則的情況實(shí)現(xiàn)起來就比較麻煩,所以在本文章中將詳細(xì)介紹一下在中C#中如何對(duì)數(shù)據(jù)進(jìn)行排序,需要的朋友可以參考下
    2024-01-01
  • C#線程隊(duì)列用法實(shí)例分析

    C#線程隊(duì)列用法實(shí)例分析

    這篇文章主要介紹了C#線程隊(duì)列用法,以實(shí)例形式分析了C#線程隊(duì)列的創(chuàng)建、運(yùn)行、等待、結(jié)束等操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-09-09
  • C#基于TCP實(shí)現(xiàn)簡單游戲客戶端的完整實(shí)例

    C#基于TCP實(shí)現(xiàn)簡單游戲客戶端的完整實(shí)例

    這篇文章主要給大家介紹了關(guān)于C#基于TCP實(shí)現(xiàn)簡單游戲客戶端的相關(guān)資料,通過本文介紹的方法可以直接實(shí)現(xiàn)游戲客戶端,是個(gè)非常適合學(xué)習(xí)的實(shí)例需要的朋友可以參考下
    2021-11-11
  • c#漢諾塔的遞歸算法與解析

    c#漢諾塔的遞歸算法與解析

    c#漢諾塔的遞歸算法與解析,需要的朋友可以參考一下
    2013-03-03
  • C#使用HttpWebRequest與HttpWebResponse模擬用戶登錄

    C#使用HttpWebRequest與HttpWebResponse模擬用戶登錄

    這篇文章主要為大家詳細(xì)介紹了C#使用HttpWebRequest與HttpWebResponse模擬用戶登錄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 使用VS2010 C#開發(fā)ActiveX控件(下),完整代碼打包下載

    使用VS2010 C#開發(fā)ActiveX控件(下),完整代碼打包下載

    我們介紹了開發(fā)、打包、發(fā)布、使用ActiveX控件的全過程。在演示程序中,我們沒有調(diào)用串口通信和讀卡器Dll程序,由于我們讀卡器的原始Dll是使用其它語言進(jìn)行開發(fā)的,對(duì)C#來說,是非托管代碼,因此我們還需要在代碼級(jí)別進(jìn)行非托管代碼的安全性設(shè)置
    2011-05-05
  • C# SQLite執(zhí)行效率的優(yōu)化教程

    C# SQLite執(zhí)行效率的優(yōu)化教程

    這篇文章主要給大家介紹了關(guān)于C# SQLite執(zhí)行效率優(yōu)化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C# SQLite具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06
  • C#實(shí)現(xiàn)多個(gè)計(jì)時(shí)器記錄不同定時(shí)時(shí)間

    C#實(shí)現(xiàn)多個(gè)計(jì)時(shí)器記錄不同定時(shí)時(shí)間

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)多個(gè)計(jì)時(shí)器記錄不同定時(shí)時(shí)間,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • c# for循環(huán)中創(chuàng)建線程執(zhí)行問題

    c# for循環(huán)中創(chuàng)建線程執(zhí)行問題

    這篇文章主要介紹了有關(guān)c# for循環(huán)中創(chuàng)建線程執(zhí)行問題,下面文章將將以舉例的方式展開for循環(huán)中創(chuàng)建線程執(zhí)行問題的內(nèi)容,需要的朋友可以參考一下,希望對(duì)你有所幫助
    2021-11-11
  • C#?Razor語法規(guī)則

    C#?Razor語法規(guī)則

    這篇文章介紹了C#?Razor的語法規(guī)則,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-01-01

最新評(píng)論

雷山县| 抚顺县| 南雄市| 从化市| 镇远县| 吴桥县| 扎赉特旗| 乌什县| 兴隆县| 宁河县| 临城县| 忻州市| 永平县| 宾阳县| 大兴区| 深水埗区| 英吉沙县| 宜州市| 大渡口区| 宜君县| 灵山县| 玛曲县| 茂名市| 扎鲁特旗| 临湘市| 集安市| 桓台县| 永仁县| 彩票| 兴安盟| 满城县| 铁岭市| 扎鲁特旗| 永修县| 新丰县| 广东省| 钟祥市| 松阳县| 车致| 和龙市| 灯塔市|