1. 程式人生 > >C# 多線程系列(四)

C# 多線程系列(四)

委托 mat 一個 方法 () 允許 pub tel bsp

Parallel類

Parallel類定義了for、foreach和invoke的靜態方法。Parallel類使用多個任務,因此使用多個線程來完成這個作業。

Parallel.For

Parallel.For()方法類似於C#的for循環語句,也是多次執行一個任務。使用Parallel.For方法,可以並行運行叠代。叠代的順序沒有定義

Parallel.For(0, 10, i =>
{
    Console.WriteLine("idx:{0}, task:{1}, thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
});
//從結果可以看出,順序是不能保證的。

也可以提前中斷for方法。for()方法的一個重載版本接受第三個Action<int, ParallelLoopState>類型的參數。使用這些參數定義一個方法,就可以調用ParallelLoopState的Break()或Stop()方法,以影響循環的結果。

  • break() ,循環應在系統方便的時候盡早停止執行當前叠代之外的叠代。
  • stop(),循環應在系統方便的時候盡早停止執行。
ParallelLoopResult result =
    Parallel.For(0, 10, (int i, ParallelLoopState pls) =>
    {
        Console.WriteLine(
"idx:{0}, task:{1}, thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId); Thread.Sleep(10); if (i > 5) pls.Break();//盡早停止,並沒有實現立即停止 }); Console.WriteLine("result.IsCompleted {0}", result.IsCompleted); Console.WriteLine("result.LowestBreakIteration {0}", result.LowestBreakIteration);

Parallel.For方法可能使用幾個線程來執行循環,如果需要對每個線程進行初始化,就可以使用Parallel.For<TLocal>()方法。出了from和to對應的值外,還接受三個委托參數。

  • 第一個參數類型是Func<TLocal>,該方法每個線程只調用一次。
  • 第二個參數為循環體定義了委托,該委托的第一個參數是循環叠代,第二個參數ParallelLoopState允許停止叠代(如上例),第三個參數是從init方法返回的值。
  • 第三個參數指定一個委托Action<TLocal>,該方法每個線程只調用一次。
Parallel.For<string>(0, 10, () =>
{
    Console.WriteLine("---init thread {0}, task{1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId);
    return string.Format("t{0}", Thread.CurrentThread.ManagedThreadId);
},
(i, pls, str1) =>
{
    Console.WriteLine("!!!body i {0} str1 {1} thread {2} task {3}", i, str1,
        Thread.CurrentThread.ManagedThreadId, Task.CurrentId);
    Thread.Sleep(10);
    return string.Format("i {0}", i);
},
(str1) =>
{
    Console.WriteLine("@@@finally {0}", str1);
});

Parallel.ForEach

Parallel.ForEach方法遍歷實現了IEnumerable的集合,其方式類似於foreach語句,但以異步方式遍歷。這裏也沒有確定遍歷順序。

string[] arr = { "name", "kkk", "iii", "yyy", "zzz", "111" };

Parallel.ForEach<string>(arr, value => Console.WriteLine(value));

Parallel.ForEach<string>(arr, (value, pls, k) =>
{
    Console.WriteLine("{0}, {1}", value, k);
    if (value == "kkk")
        pls.Stop();
});

Parallel.Invoke

如果多個任務應並行運行,就可以使用Parallel.Invoke方法。

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

C# 多線程系列(四)