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

C#用Parallel.Invoke方法盡可能并行執(zhí)行提供的每個(gè)線程

 更新時(shí)間:2024年01月22日 09:16:00   作者:wenchm  
本文主要介紹了C#用Parallel.Invoke方法盡可能并行執(zhí)行提供的每個(gè)線程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

盡可能并行執(zhí)行提供的每個(gè)操作。使用Parallel.Invoke 方法。

最簡(jiǎn)單,最簡(jiǎn)潔的將串行的代碼并行化。 

一、重載

Invoke(Action[])盡可能并行執(zhí)行提供的每個(gè)操作。
Invoke(ParallelOptions, Action[])執(zhí)行所提供的每個(gè)操作,而且盡可能并行運(yùn)行,除非用戶取消了操作。

二、Invoke(Action[])

盡可能并行執(zhí)行提供的每個(gè)操作。 

1.定義

public static void Invoke (params Action[] actions);

參數(shù)
actions    Action[]
要執(zhí)行的 Action 數(shù)組。

例外
ArgumentNullException
actions 參數(shù)為 null。

AggregateException
當(dāng) actions 數(shù)組中的任何操作引發(fā)異常時(shí)引發(fā)的異常。

ArgumentException
actions數(shù)組包含 null 個(gè)元素。

2.示例

 Invoke方法經(jīng)常與其他方法、匿名委托和 lambda 表達(dá)式配合使用,實(shí)現(xiàn)并行方法的線程同步。

// Parallel.Invoke()方法
// 將 Invoke 方法與其他方法、匿名委托和 lambda 表達(dá)式結(jié)合使用。
namespace ConsoleApp15
{
    class ParallelInvokeDemo
    {
        /// <summary>
        /// 執(zhí)行每個(gè)任務(wù)的線程可能不同。
        /// 不同的執(zhí)行中線程分配可能不同。
        /// 任務(wù)可能按任何順序執(zhí)行。
        /// </summary>
        static void Main()
        {
            try
            {
                Parallel.Invoke(
                    BasicAction,    // Param #0 - static method
                    () =>           // Param #1 - lambda expression
                    {
                        Console.WriteLine("Method=beta, Thread={0}", Environment.CurrentManagedThreadId);
                    },
                    delegate ()     // Param #2 - in-line delegate
                    {
                        Console.WriteLine("Method=gamma, Thread={0}", Environment.CurrentManagedThreadId);
                    }
                );
            }
            // 一般不會(huì)出現(xiàn)異常,但如萬(wàn)一拋出異常, 
            // 它將被包裝在 AggregateException 中并傳播到主線程。
            catch (AggregateException e)
            {
                Console.WriteLine("An action has thrown an exception. THIS WAS UNEXPECTED.\n{0}", e.InnerException!.ToString());
            }
        }

        static void BasicAction()
        {
            Console.WriteLine("Method=alpha, Thread={0}", Environment.CurrentManagedThreadId);
        }
    }
}
// 運(yùn)行結(jié)果:
/*
Method=beta, Thread=4
Method=alpha, Thread=1
Method=gamma, Thread=10

 */

三、Invoke(ParallelOptions, Action[])

執(zhí)行所提供的每個(gè)操作,而且盡可能并行運(yùn)行,除非用戶取消了操作。

1.定義 

public static void Invoke (System.Threading.Tasks.ParallelOptions parallelOptions, params Action[] actions);

參數(shù)
parallelOptions    ParallelOptions
一個(gè)對(duì)象,用于配置此操作的行為。

actions    Action[]
要執(zhí)行的操作數(shù)組。

例外
OperationCanceledException
CancellationToken 處于 parallelOptions 設(shè)置。

ArgumentNullException
actions 參數(shù)為 null。
或 - parallelOptions 參數(shù)為 null。
AggregateException
當(dāng) actions 數(shù)組中的任何操作引發(fā)異常時(shí)引發(fā)的異常。

ArgumentException
actions數(shù)組包含 null 個(gè)元素。

ObjectDisposedException
在 parallelOptions 中與 CancellationTokenSource 關(guān)聯(lián)的 CancellationToken 已被釋放。

注解
此方法可用于執(zhí)行一組可能并行的操作。 使用結(jié)構(gòu)傳入 ParallelOptions 的取消令牌使調(diào)用方能夠取消整個(gè)操作。

2. 常用的使用方法

Parallel.Invoke(
   () => { },
   () => { },
   () => { }
   );

(1)示例1

  • 一個(gè)任務(wù)是可以分解成多個(gè)任務(wù),采用分而治之的思想;
  • 盡可能的避免子任務(wù)之間的依賴性,因?yàn)樽尤蝿?wù)是并行執(zhí)行,所以就沒(méi)有誰(shuí)一定在前,誰(shuí)一定在后的規(guī)定了;
  • 主線程必須等Invoke中的所有方法執(zhí)行完成后返回才繼續(xù)向下執(zhí)行。暗示以后設(shè)計(jì)并行的時(shí)候,要考慮每個(gè)Task任務(wù)盡可能差不多,如果相差很大,比如一個(gè)時(shí)間非常長(zhǎng),其他都比較短,這樣一個(gè)線程可能會(huì)影響整個(gè)任務(wù)的性能。這點(diǎn)非常重要;
  • 沒(méi)有固定的順序,每個(gè)Task可能是不同的線程去執(zhí)行,也可能是相同的;
namespace ConsoleApp16
{
    internal class Program
    {
       
        private static void Main(string[] args)
        {
            ArgumentNullException.ThrowIfNull(args);
            ParallelMothed();
            static void ParallelMothed()
            {
                Parallel.Invoke(Run1, Run2);  //這里的Run1 Run2 都是方法。
            }
        }
        static void Run1()
        {
            Console.WriteLine("我是任務(wù)一,我跑了3s");
            Thread.Sleep(3000);
        }

        static void Run2()
        {
            Console.WriteLine("我是任務(wù)二,我跑了5s");
            Thread.Sleep(5000);
        }
    }
}
//運(yùn)行結(jié)果:
/*
我是任務(wù)二,我跑了5s
我是任務(wù)一,我跑了3s

 */

(2)示例2

如果調(diào)用的方法是有參數(shù)的,如何處理?同理,直接帶上參數(shù)就可以,

Parallel.Invoke(() => Task1("task1"), () => Task2("task2"), () => Task3("task3"));
// Invoke帶參數(shù) 調(diào)用 
using System.Diagnostics;

namespace ConsoleApp17
{
    class ParallelInvoke
    {
        public static void Main(string[] args)
        {
            ArgumentNullException.ThrowIfNull(args);
            Stopwatch stopWatch = new();
            Console.WriteLine("主線程:{0}線程ID : {1};開始", "Main", Environment.CurrentManagedThreadId);
            stopWatch.Start();
            Parallel.Invoke(
                () => Task1("task1"), 
                () => Task2("task2"), 
                () => Task3("task3")
                );
            stopWatch.Stop();
            Console.WriteLine("主線程:{0}線程ID : {1};結(jié)束,共用時(shí){2}ms", "Main", Environment.CurrentManagedThreadId, stopWatch.ElapsedMilliseconds);
            Console.ReadKey();
        }

        private static void Task1(string data)
        {
            Thread.Sleep(5000);
            Console.WriteLine("任務(wù)名:{0}線程ID : {1}", data, Environment.CurrentManagedThreadId);
        }

        private static void Task2(string data)
        {
            Console.WriteLine("任務(wù)名:{0}線程ID : {1}", data, Environment.CurrentManagedThreadId);
        }

        private static void Task3(string data)
        {
            Console.WriteLine("任務(wù)名:{0}線程ID : {1}", data, Environment.CurrentManagedThreadId);
        }
    }
}
//運(yùn)行結(jié)果:
/*
主線程:Main線程ID : 1;開始
任務(wù)名:task2線程ID : 4
任務(wù)名:task3線程ID : 7
任務(wù)名:task1線程ID : 1
主線程:Main線程ID : 1;結(jié)束,共用時(shí)5020ms
 */

(3)Stopwatch類

 提供一組方法和屬性,可用于準(zhǔn)確地測(cè)量運(yùn)行時(shí)間。

其中,Stopwatch.Start 方法和Stopwatch.Stop 方法

public class Stopwatch

使用 Stopwatch 類來(lái)確定應(yīng)用程序的執(zhí)行時(shí)間。

// 使用 Stopwatch 類來(lái)確定應(yīng)用程序的執(zhí)行時(shí)間
using System.Diagnostics;
class Program
{
    static void Main(string[] args)
    {
        ArgumentNullException.ThrowIfNull(args);

        Stopwatch stopWatch = new();
        stopWatch.Start();
        Thread.Sleep(10000);
        stopWatch.Stop();
        // Get the elapsed time as a TimeSpan value.
        TimeSpan ts = stopWatch.Elapsed;

        // Format and display the TimeSpan value.
        string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            ts.Hours, ts.Minutes, ts.Seconds,
            ts.Milliseconds / 10);
        Console.WriteLine("RunTime " + elapsedTime);
    }
}
//運(yùn)行結(jié)果:
/*
RunTime 00:00:10.01

 */
// 使用 Stopwatch 類來(lái)計(jì)算性能數(shù)據(jù)。
using System.Diagnostics;

namespace StopWatchSample
{
    class OperationsTimer
    {
        public static void Main(string[] args)
        {
            ArgumentNullException.ThrowIfNull(args);

            DisplayTimerProperties();

            Console.WriteLine();
            Console.WriteLine("Press the Enter key to begin:");
            Console.ReadLine();
            Console.WriteLine();

            TimeOperations();
        }

        public static void DisplayTimerProperties()
        {
            // Display the timer frequency and resolution.
            if (Stopwatch.IsHighResolution)
            {
                Console.WriteLine("Operations timed using the system's high-resolution performance counter.");
            }
            else
            {
                Console.WriteLine("Operations timed using the DateTime class.");
            }

            long frequency = Stopwatch.Frequency;
            Console.WriteLine("  Timer frequency in ticks per second = {0}",frequency);
            long nanosecPerTick = (1000L * 1000L * 1000L) / frequency;
            Console.WriteLine("  Timer is accurate within {0} nanoseconds",nanosecPerTick);
        }

        private static void TimeOperations()
        {
            long nanosecPerTick = (1000L * 1000L * 1000L) / Stopwatch.Frequency;
            const long numIterations = 10000;

            // Define the operation title names.
            string[] operationNames = {"Operation: Int32.Parse(\"0\")",
                                           "Operation: Int32.TryParse(\"0\")",
                                           "Operation: Int32.Parse(\"a\")",
                                           "Operation: Int32.TryParse(\"a\")"};

            // Time four different implementations for parsing
            // an integer from a string.

            for (int operation = 0; operation &lt;= 3; operation++)
            {
                // Define variables for operation statistics.
                long numTicks = 0;
                long numRollovers = 0;
                long maxTicks = 0;
                long minTicks = long.MaxValue;
                int indexFastest = -1;
                int indexSlowest = -1;
                Stopwatch time10kOperations = Stopwatch.StartNew();

                // Run the current operation 10001 times.
                // The first execution time will be tossed
                // out, since it can skew the average time.

                for (int i = 0; i &lt;= numIterations; i++)
                {
                    long ticksThisTime = 0;
                    int inputNum;
                    Stopwatch timePerParse;

                    switch (operation)
                    {
                        case 0:
                            // Parse a valid integer using
                            // a try-catch statement.
                            // Start a new stopwatch timer.
                            timePerParse = Stopwatch.StartNew();

                            try
                            {
                                inputNum = int.Parse("0");
                            }
                            catch (FormatException)
                            {
                                inputNum = 0;
                            }

                            // Stop the timer, and save the
                            // elapsed ticks for the operation.

                            timePerParse.Stop();
                            ticksThisTime = timePerParse.ElapsedTicks;
                            break;
                        case 1:
                            // Parse a valid integer using
                            // the TryParse statement.

                            // Start a new stopwatch timer.
                            timePerParse = Stopwatch.StartNew();

                            if (!int.TryParse("0", out inputNum))
                            {
                                inputNum = 0;
                            }

                            // Stop the timer, and save the
                            // elapsed ticks for the operation.
                            timePerParse.Stop();
                            ticksThisTime = timePerParse.ElapsedTicks;
                            break;
                        case 2:
                            // Parse an invalid value using
                            // a try-catch statement.

                            // Start a new stopwatch timer.
                            timePerParse = Stopwatch.StartNew();

                            try
                            {
                                inputNum = int.Parse("a");
                            }
                            catch (FormatException)
                            {
                                inputNum = 0;
                            }

                            // Stop the timer, and save the
                            // elapsed ticks for the operation.
                            timePerParse.Stop();
                            ticksThisTime = timePerParse.ElapsedTicks;
                            break;
                        case 3:
                            // Parse an invalid value using
                            // the TryParse statement.

                            // Start a new stopwatch timer.
                            timePerParse = Stopwatch.StartNew();

                            if (!int.TryParse("a", out inputNum))
                            {
                                inputNum = 0;
                            }

                            // Stop the timer, and save the
                            // elapsed ticks for the operation.
                            timePerParse.Stop();
                            ticksThisTime = timePerParse.ElapsedTicks;
                            break;

                        default:
                            break;
                    }

                    // Skip over the time for the first operation,
                    // just in case it caused a one-time
                    // performance hit.
                    if (i == 0)
                    {
                        time10kOperations.Reset();
                        time10kOperations.Start();
                    }
                    else
                    {

                        // Update operation statistics
                        // for iterations 1-10000.
                        if (maxTicks &lt; ticksThisTime)
                        {
                            indexSlowest = i;
                            maxTicks = ticksThisTime;
                        }
                        if (minTicks &gt; ticksThisTime)
                        {
                            indexFastest = i;
                            minTicks = ticksThisTime;
                        }
                        numTicks += ticksThisTime;
                        if (numTicks &lt; ticksThisTime)
                        {
                            // Keep track of rollovers.
                            numRollovers++;
                        }
                    }
                }

                // Display the statistics for 10000 iterations.

                time10kOperations.Stop();
                long milliSec = time10kOperations.ElapsedMilliseconds;
                Console.WriteLine();
                Console.WriteLine("{0} Summary:", operationNames[operation]);
                Console.WriteLine("  Slowest time:  #{0}/{1} = {2} ticks",
                    indexSlowest, numIterations, maxTicks);
                Console.WriteLine("  Fastest time:  #{0}/{1} = {2} ticks",
                    indexFastest, numIterations, minTicks);
                Console.WriteLine("  Average time:  {0} ticks = {1} nanoseconds",
                    numTicks / numIterations,
                    (numTicks * nanosecPerTick) / numIterations);
                Console.WriteLine("  Total time looping through {0} operations: {1} milliseconds",
                    numIterations, milliSec);
            }
        }
    }
}
//運(yùn)行結(jié)果:
/*
Operations timed using the system's high-resolution performance counter.
  Timer frequency in ticks per second = 10000000
  Timer is accurate within 100 nanoseconds

 */

1.Stopwatch.Start 方法

開始或繼續(xù)測(cè)量某個(gè)時(shí)間間隔的運(yùn)行時(shí)間。

前例中有示例。 

public void Start ();

2.Stopwatch.Stop 方法

停止測(cè)量某個(gè)時(shí)間間隔的運(yùn)行時(shí)間。

public void Stop ();

前例中有示例。

到此這篇關(guān)于C#用Parallel.Invoke方法盡可能并行執(zhí)行提供的每個(gè)線程的文章就介紹到這了,更多相關(guān)C# Parallel.Invoke并行執(zhí)行提供線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C# Winform多屏幕多顯示器編程技巧實(shí)例

    C# Winform多屏幕多顯示器編程技巧實(shí)例

    這篇文章主要介紹了C# Winform多屏幕多顯示器編程技巧實(shí)例,本文直接給出代碼實(shí)例,需要的朋友可以參考下
    2015-06-06
  • C#獲取電腦機(jī)器碼的實(shí)用小工具(附代碼)

    C#獲取電腦機(jī)器碼的實(shí)用小工具(附代碼)

    在日常軟件開發(fā)或電腦維護(hù)中,我們常常需要識(shí)別一臺(tái)電腦的唯一硬件標(biāo)識(shí),本文介紹的這段?C#?代碼,正是為了幫助編程新手快速獲取當(dāng)前?Windows?電腦的主板序列號(hào)、CPU?ID?和硬盤序列號(hào),并以簡(jiǎn)潔的彈窗形式呈現(xiàn)結(jié)果,希望對(duì)大家有所幫助
    2026-04-04
  • C#實(shí)現(xiàn)在兩個(gè)數(shù)字之間生成隨機(jī)數(shù)的方法

    C#實(shí)現(xiàn)在兩個(gè)數(shù)字之間生成隨機(jī)數(shù)的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)在兩個(gè)數(shù)字之間生成隨機(jī)數(shù)的方法,在一些特殊場(chǎng)景會(huì)用到哦,需要的朋友可以參考下
    2014-08-08
  • C#使用NAudio錄音并導(dǎo)出錄音數(shù)據(jù)

    C#使用NAudio錄音并導(dǎo)出錄音數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了C#如何使用NAudio實(shí)現(xiàn)錄音功能并導(dǎo)出錄音數(shù)據(jù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • C#中Linq的入門教程

    C#中Linq的入門教程

    這篇文章介紹了C#中Linq的基礎(chǔ)操作,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • Unity3D實(shí)現(xiàn)模型隨機(jī)切割

    Unity3D實(shí)現(xiàn)模型隨機(jī)切割

    這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)模型隨機(jī)切割,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • c# 獲得本地ip地址的三種方法

    c# 獲得本地ip地址的三種方法

    這篇文章主要介紹了c# 獲得本地ip地址的三種方法,幫助大家更好的理解和實(shí)用c#,感興趣的朋友可以了解下
    2020-12-12
  • C#中使用HttpPost調(diào)用WebService的方法

    C#中使用HttpPost調(diào)用WebService的方法

    這篇文章介紹了C#中使用HttpPost調(diào)用WebService的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • 解析c#操作excel后關(guān)閉excel.exe的方法

    解析c#操作excel后關(guān)閉excel.exe的方法

    C#和Asp.net下excel進(jìn)程一被打開,有時(shí)就無(wú)法關(guān)閉,尤其是website.對(duì)關(guān)閉該進(jìn)程有過(guò)GC、release等方法,但這些方法并不是在所有情況下均適用
    2013-07-07
  • BarCode條形碼基于C# GDI+ 的實(shí)現(xiàn)方法詳解

    BarCode條形碼基于C# GDI+ 的實(shí)現(xiàn)方法詳解

    本篇文章介紹了,BarCode條形碼基于C# GDI+ 的實(shí)現(xiàn)方法詳解。需要的朋友參考下
    2013-05-05

最新評(píng)論

唐河县| 陆川县| 广昌县| 桂林市| 依安县| 南川市| 仪陇县| 玛多县| 海安县| 太仆寺旗| 嘉善县| 三门县| 江源县| 翼城县| 白沙| 宝应县| 沁阳市| 屏山县| 登封市| 揭西县| 桃源县| 仁怀市| 渭源县| 达孜县| 焦作市| 特克斯县| 两当县| 玉环县| 乌苏市| 大理市| 郁南县| 通州市| 德格县| 定远县| 天柱县| 宝坻区| 上高县| 宁武县| 禹州市| 乐业县| 开阳县|