探究Visual Studio 2010中Parallel的使用(2) 软件测试
对Parallel.Invoke进行控制
Parallel.Invoke提供了一个重载版本,它可以接受一个ParallelOptions对象作为参数,对Parallel.Invoke的执行进行控制。通过这个对象,我们可以控制并行的最大线程数,各个任务是否取消执行等等。例如,在一个智能化的家中,系统会判断主人是否离开房间,如果主人离开了房间,则自动关闭屋子里的各种电器。利用Parallel.Invoke我们可以实现如下:
public static void PInvokeCancel() { // 创建取消对象 CancellationTokenSource cts = new CancellationTokenSource(); // 利用取消对象,创建ParallelOptions ParallelOptions pOption = new ParallelOptions() { CancellationToken = cts.Token }; // 设置最大线程数 pOption.MaxDegreeOfParallelism = 2; // 创建一个守护监视进程 Task.Factory.StartNew(() => { Console.WriteLine("Cancellation in 5 sec."); Thread.Sleep(5000); // 取消,结束任务的执行 cts.Cancel(); Console.WriteLine("Canceled requested"); }); try { // 以ParallelOptions作为参数, // 调用Parallel.Invoke Parallel.Invoke(pOption, () => ShutdownLights(pOption.CancellationToken), () => ShutdownComputer(pOption.CancellationToken)); //输出执行结果 Console.WriteLine("Lights and computer are tuned off."); } catch (Exception e) { Console.WriteLine(e.Message); } } private static void ShutdownLights(CancellationToken token) { while (!token.IsCancellationRequested) { Console.WriteLine("Light is on. " ); Thread.Sleep(1000); } } private static void ShutdownComputer(CancellationToken token) { while (!token.IsCancellationRequested) { Console.WriteLine("Computer is on." ); Thread.Sleep(1000); } }
除了这种方式之外,ParallelOptions更多地应用在取消任务队列中还未来得及执行的任务。当我们限制了最大并发线程数的时候,如果需要通过Parallel.Invoke执行的任务较多,则有可能部分任务在队列中排队而得不到及时的执行,如果到了一定的条件这些任务还没有执行,我们可能取消这些任务。一个恰当的现实生活中的例子就是火车站买票。火车站买票的人很多,但是售票的窗口有限,当到了下班时间后,窗口就不再售票了,也就是剩下的售票任务需要取消掉。我们可以用下面的代码来模拟这样一个场景:
public static void PInvokeCancel() { // 创建取消对象 CancellationTokenSource cts = new CancellationTokenSource(); // 利用取消对象,创建ParallelOptions ParallelOptions pOption = new ParallelOptions() { CancellationToken = cts.Token }; // 设置最大线程数,也就相当于20个售票窗口 pOption.MaxDegreeOfParallelism = 20; // 创建一个守护监视进程 // 当到下班时间后就取消剩下的售票活动 Task.Factory.StartNew(() => { Console.WriteLine("Cancellation in 5 sec."); Thread.Sleep(5000); // 取消,结束任务的执行 cts.Cancel(); Console.WriteLine("Canceled requested"); }); try { // 创建售票活动 Action[] CustomerServices = CreateCustomerService(1000); // 以ParallelOptions作为参数, // 调用Parallel.Invoke Parallel.Invoke(pOption, CustomerServices); } catch (Exception e) { // 当任务取消后,抛出一个异常 Console.WriteLine(e.Message); } } // 创建售票的活动 static Action[] CreateCustomerService(int n) { Action[] result = new Action[n]; for (int i = 0; i < n; i++) { result[i] = () => { Console.WriteLine("Customer Service {0}", Task.CurrentId); // 模拟售票需要的时间 Thread.Sleep(2000); }; } return result; }