C# 多线程系列(四)

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# 多线程系列(五)

posted @ 2018-02-24 17:29  吴筱军  阅读(210)  评论(0编辑  收藏  举报