欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#多線程之Parallel類(lèi)的用法

 更新時(shí)間:2022年04月13日 09:33:09   作者:Ruby_Lu  
這篇文章介紹了C#多線程之Parallel類(lèi)的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

Parallel類(lèi)是對(duì)線程的一個(gè)抽象。該類(lèi)位于System.Threading.Tasks名稱(chēng)空間中,提供了數(shù)據(jù)和任務(wù)并行性。

Paraller類(lèi)定義了數(shù)據(jù)并行地For和ForEach的靜態(tài)方法,以及任務(wù)并行的Invoke的靜態(tài)方法。Parallel.For()和Parallel.ForEach()方法在每次迭代中調(diào)用相同的代碼,Paraller.Invoke()允許調(diào)用不同的方法。

1.Parallel.For

Parallel.For()方法類(lèi)似C#語(yǔ)法的for循環(huán)語(yǔ)句,多次執(zhí)行一個(gè)任務(wù)。但該方法并行運(yùn)行迭代,迭代的順序沒(méi)有定義。

Parallel.For()方法中,前兩個(gè)參數(shù)定義了循環(huán)的開(kāi)頭和結(jié)束,第三個(gè)參數(shù)是一個(gè)Action委托。Parallel.For方法返回類(lèi)型是ParallelLoopResult結(jié)構(gòu),它提供了循環(huán)是否結(jié)束的信息。

Parallel.For有多個(gè)重載版本和多個(gè)泛型重載版本。

示例:

static void ForTest()
        {
            ParallelLoopResult plr =
                Parallel.For(0,10,i => {
                    Console.WriteLine("{0},task:{1},thread:{2}",i,Task.CurrentId,Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(5000);
                });

            if (plr.IsCompleted)
                Console.WriteLine("completed!");

        }

輸出:

任務(wù)不一定映射到一個(gè)線程上。線程也可以被不同的任務(wù)重用。

上面的例子,使用了.NET 4.5中新增的Thread.Sleep方法,而不是Task.Delay方法。Task.Delay是一個(gè)異步(http://www.cnblogs.com/afei-24/p/6757361.html)方法,用于釋放線程供其它任務(wù)使用。

示例:

static void ForTestDelay()
        {
            ParallelLoopResult plr =
                Parallel.For(0, 10,async i => {
                    Console.WriteLine("{0},task:{1},thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
                    await Task.Delay(1000);
                    Console.WriteLine("{0},task:{1},thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
                });

            if (plr.IsCompleted)
                Console.WriteLine("completed!");

            Console.ReadKey();

        }

輸出:

上面代碼使用了await關(guān)鍵字進(jìn)行延遲,輸出結(jié)果顯示延遲前后的代碼運(yùn)行在不同的線程中。而且延遲后的任務(wù)不再存在,只留下線程,這里還重用了前面的線程。另一個(gè)重要的方面是,Parallel類(lèi)的For方法并沒(méi)有等待延遲,而是直接完成。parallel類(lèi)只等待它創(chuàng)建的任務(wù),而不等待其它后臺(tái)活動(dòng)。所以上面代碼使用了Console.ReadKey();使主線程一直運(yùn)行,不然很可能看不到后面的輸出。

2.提前停止Parallel.For

For()方法的一個(gè)重載版本接受第三個(gè)Action<int,ParallelLoopState>委托類(lèi)型的參數(shù)。使用這個(gè)方法可以調(diào)用ParallelLoopState的Break()或Stop()方法,以停止循環(huán)。

注意,前面說(shuō)到,迭代的順序是沒(méi)有定義的。

示例:

static void ForStop()
        {
            ParallelLoopResult plr =
                Parallel.For(0,10,(int i,ParallelLoopState pls)=> {
                    Console.WriteLine("{0},task:{1},thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
                    if (i > 5)
                        pls.Break();
                });

            Console.WriteLine("is completed:{0}",plr.IsCompleted);
            Console.WriteLine("最低停止索引:{0}",plr.LowestBreakIteration);
        }

輸出:

迭代值在大于5時(shí)中斷,但其它已開(kāi)始的任務(wù)同時(shí)執(zhí)行。

3.對(duì)Parallel.For中的每個(gè)線程初始化

Parallel.For方法使用多個(gè)線程來(lái)執(zhí)行循環(huán),如果需要對(duì)每個(gè)線程進(jìn)行初始化,就可以使用Parallel.For<TLocal>()方法。除了from和to對(duì)應(yīng)的值之外,Parallel.For方法的泛型版本還接受3個(gè)委托參數(shù):

第一個(gè)委托參數(shù)的類(lèi)型是Func<TLocal>,這個(gè)方法僅對(duì)用于執(zhí)行迭代的每個(gè)線程調(diào)用每一次。

第二個(gè)委托參數(shù)為循環(huán)體定義了委托。該參數(shù)類(lèi)型是Func<int, ParallelLoopState, TLocal, TLocal>。其中第一個(gè)參數(shù)是循環(huán)迭代,第二個(gè)參數(shù)ParallelLoopState允許停止循環(huán),第三個(gè)參數(shù)接受從上面參數(shù)委托Func<TLocal>返回的值,該委托還需返回一個(gè)TLocal類(lèi)型的值。該方法對(duì)每次迭代調(diào)用。

第三個(gè)委托參數(shù)指定一個(gè)委托Action<TLocal>,接受第二個(gè)委托參數(shù)的返回值。這個(gè)方法僅對(duì)用于執(zhí)行迭代的每個(gè)線程調(diào)用每一次。

示例:

static void ForInit()
            {
                ParallelLoopResult plr =
                    Parallel.For(0,10,()=> {
                        Console.WriteLine("init thread:{0},task:{1}",Thread.CurrentThread.ManagedThreadId,Task.CurrentId);
                        return Thread.CurrentThread.ManagedThreadId.ToString();
                    },
                    (i, pls,strInit)=> {
                        Console.WriteLine("body:{0},strInit:{1},thraed:{2},task:{3}",i,strInit,Thread.CurrentThread.ManagedThreadId,Task.CurrentId);
                        return i.ToString();
                    },
                    (strI)=> {
                        Console.WriteLine("finally {0}",strI);
                    });
            }

輸出:

4.Parallel.ForEach

Parallel.ForEach方法遍歷實(shí)現(xiàn)了IEnumerable的集合,類(lèi)似于foreach,但以異步方式遍歷。沒(méi)有確定遍歷順序。

示例:

static void ForeachTest()
    {
        string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve" };
        ParallelLoopResult plr =  Parallel.ForEach<string>(data, s =>
        {
            Console.WriteLine(s);
        });
 
        if (plr.IsCompleted)
            Console.WriteLine("completed!");
    }

如果需要中斷,可以使用ForEach的重載版本和參數(shù)ParallelLoopState。

訪問(wèn)索引器:

ParallelLoopResult plr1 = Parallel.ForEach<string>(data, (s,pls,l) =>
            {
                Console.WriteLine("data:{0},index:{1}",s,l);
            });

5.Parallel.Invoke

如果多個(gè)任務(wù)并行運(yùn)行,可以使用Parallel.Invoke方法。該方法允許傳遞一個(gè)Action委托數(shù)組。

static void ParallerInvoke()
        {
            Action[] funs = { Fun1,Fun2};

            Parallel.Invoke(funs);
        }

        static void Fun1()
        {
            Console.WriteLine("f1");
            Console.WriteLine("task:{0},thread:{1}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
        }
        static void Fun2()
        {
            Console.WriteLine("f2");
            Console.WriteLine("task:{0},thread:{1}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
        }

到此這篇關(guān)于C#多線程之Parallel類(lèi)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#添加Windows服務(wù) 定時(shí)任務(wù)

    C#添加Windows服務(wù) 定時(shí)任務(wù)

    這篇文章主要為大家詳細(xì)介紹了C#添加Windows服務(wù),定時(shí)任務(wù)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Linq兩個(gè)List集合取交集的實(shí)現(xiàn)

    Linq兩個(gè)List集合取交集的實(shí)現(xiàn)

    這篇文章主要介紹了Linq兩個(gè)List集合取交集的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • WinForm防止程序重復(fù)運(yùn)行的方法分析

    WinForm防止程序重復(fù)運(yùn)行的方法分析

    這篇文章主要介紹了WinForm防止程序重復(fù)運(yùn)行的方法,通過(guò)記錄窗口句柄實(shí)現(xiàn)防止WinForm程序重復(fù)運(yùn)行的功能,需要的朋友可以參考下
    2017-05-05
  • C#中的LINQ?to?Objects詳解(1)

    C#中的LINQ?to?Objects詳解(1)

    本文詳細(xì)講解了C#中的LINQ?to?Objects,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • c# RPC框架的使用簡(jiǎn)介

    c# RPC框架的使用簡(jiǎn)介

    這篇文章主要介紹了c# RPC框架的使用簡(jiǎn)介,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-02-02
  • VS2019打包WPF安裝程序最新教程(圖文詳解)

    VS2019打包WPF安裝程序最新教程(圖文詳解)

    這篇文章主要介紹了VS2019打包WPF安裝程序最新教程,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • C#結(jié)合JavaScript實(shí)現(xiàn)秒殺倒計(jì)時(shí)的方法

    C#結(jié)合JavaScript實(shí)現(xiàn)秒殺倒計(jì)時(shí)的方法

    這篇文章主要介紹了C#結(jié)合JavaScript實(shí)現(xiàn)秒殺倒計(jì)時(shí)的方法,涉及C#結(jié)合javascript操作時(shí)間的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C#實(shí)現(xiàn)微信紅包功能

    C#實(shí)現(xiàn)微信紅包功能

    這篇文章主要介紹了C#實(shí)現(xiàn)微信紅包功能,使用正態(tài)分布計(jì)算紅包金額,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 詳解C#實(shí)例化對(duì)象的三種方式及性能對(duì)比

    詳解C#實(shí)例化對(duì)象的三種方式及性能對(duì)比

    這篇文章主要介紹了C#實(shí)例化對(duì)象的三種方式及性能對(duì)比,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • C#如何遍歷Dictionary

    C#如何遍歷Dictionary

    這篇文章主要為大家詳細(xì)介紹了C#遍歷Dictionary的方法,.NET中的Dictionary是鍵/值對(duì)的集合,使用起來(lái)比較方便,Dictionary也可以用KeyValuePair來(lái)迭代遍歷,感興趣的小伙伴們可以參考一下
    2016-04-04

最新評(píng)論