线程、任务和同步学习笔记(四)

1、抽象线程类Parallel的For和ForEach方法可以多次调用同一个方法。Parallel类的Invoke方法允许同时调用不同的方法。

 1 using System;
 2 using System.Threading;
 3 using System.Threading.Tasks;
 4 
 5 class Program
 6 {
 7     static void Main(string[] args)
 8     {
 9         ParallelLoopResult result = Parallel.For(0, 10, i =>
10         {
11             Console.WriteLine("{0}, task: {1}, thread: {2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
12             Thread.Sleep(10);
13         });
14         Console.WriteLine(result);
15         Console.WriteLine(result.IsCompleted);
16     }
17 }

运行结果:

2、For方法的循环可以中断,中断的方式是使用ParallelLoopState的Break方法。

 1 using System;
 2 using System.Threading;
 3 using System.Threading.Tasks;
 4 
 5 class Program
 6 {
 7     static void Main(string[] args)
 8     {
 9         ParallelLoopResult result = Parallel.For(0, 30, (int i, ParallelLoopState state) =>
10         {
11             Console.WriteLine("{0}, task: {1}, thread: {2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
12             Thread.Sleep(10);
13             if (i > 10)
14             {
15                 state.Break();
16             }
17         });
18         Console.WriteLine(result.IsCompleted);
19         Console.WriteLine("Lowest break iteration: {0}.", result.LowestBreakIteration);
20     }
21 }

运行结果:

从上图所示的运行结果可以看出,程序并不能保证循环变量 i 的值都满足条件。

3、For方法的泛型版本还接受3个委托参数。第一个参数的类型是Func<TLocal>,该方法在每个线程中调用一次;第二个参数为循环体定义了委托;第三个参数的类型为Action<TLocal>,该方法是一个线程退出方法,它同样也是在每个线程中调用一次。

 1 using System;
 2 using System.Threading;
 3 using System.Threading.Tasks;
 4 
 5 class Program
 6 {
 7     static void Main(string[] args)
 8     {
 9         Parallel.For<string>(0, 20,
10         () => 
11         {
12             Console.WriteLine("Init thread {0}, task {1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId);
13             return string.Format("Return ONE, thread id: {0}", Thread.CurrentThread.ManagedThreadId);
14         },
15         (int i, ParallelLoopState state, string str) =>
16         {
17             Console.WriteLine("Body i {0}, str {1}, thread {2}, task {3}", i, str, Thread.CurrentThread.ManagedThreadId, Task.CurrentId);
18             Thread.Sleep(10);
19             return string.Format("Return TWO, i: {0}", i);
20         },
21         (str) =>
22         {
23             Console.WriteLine("Finally {0}", str);
24         });
25     }
26 }

运行结果:

4、Foreach方法实现了IEnumerable接口,类似于foreach语句,但是它以异步方式遍历,没有确定的遍历顺序。

 1 using System;
 2 using System.Threading;
 3 using System.Threading.Tasks;
 4 
 5 class Program
 6 {
 7     static void Main(string[] args)
 8     {
 9         string[] data = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "zero" };
10         ParallelLoopResult result = Parallel.ForEach<string>(data, s =>
11         {
12             Console.WriteLine(s);
13         });
14     }
15 }

运行结果:

5、使用Parallel类的Invoke方法可以并行运行多个方法。Invoke方法允许传递一个Action委托数组。

 1 using System;
 2 using System.Threading;
 3 using System.Threading.Tasks;
 4 
 5 class Program
 6 {
 7     static void Main(string[] args)
 8     {
 9         Parallel.Invoke(ListenMusic, PlayGame);
10     }
11 
12     static void ListenMusic()
13     {
14         Console.WriteLine("Listening music.");
15     }
16     static void PlayGame()
17     {
18         Console.WriteLine("Playing game.");
19     }
20 }

运行结果:

posted @ 2016-06-01 07:21  如意猴™  阅读(145)  评论(0编辑  收藏  举报