码迷,mamicode.com
首页 > 其他好文 > 详细

Parallel Programming-Task Base

时间:2015-11-09 23:52:17      阅读:280      评论:0      收藏:0      [点我收藏+]

标签:

Parallel.For/ForEach是数据层面的并行,本文所讲的Task是将不同的操作并行执行,本文主要内容:

  1. Task的工作模型
  2. 初始化Task
  3. 完成Task
  4. 取消Task

一、Task工作模型

.Net中Task的工作模式是Fork/Join或者Master/Worker模式。核心思想是Master负责接受Client的请求,并且负责将请求分配给最终的Wroker,Worker执行完自己的工作后分别返回给Master。由Master汇总最终的结果并且返回给Client。

 技术分享

在.Net的Task并行编程中。一个Worker代表一个Task。

二、初始化Task

2.1 Parallel.Invoke

Parallel.Invoke是最简单的办法Task并行编程模式。

2.2 TaskFactory.StartNew

该方法会创建一个Task用于执行作为参数的方法。

 

    class TaskDemo
    {
        public void Action1()
        {
            Console.WriteLine("in action1");
        }

        public void Action2()
        {
            Console.WriteLine("in action2");
        }

        public void StartTasks()
        {
            var task1 = Task.Factory.StartNew(Action1);
            var task2 = Task.Factory.StartNew(Action2);
            Task.WaitAll(task1, task2);
        }
    }

以上代码使用TaskFactory.StartNew方法创建了两个Task。task1用于执行Action1,task2用于执行Action2.

StartNew只是创建了一个task,并将该task加入到一个工作队列(work queue),当时该Task并没有马上执行,task什么时候执行是由TaskScheduler决定。TaskScheduler会将需要执行的task从中拿出来,然后才开始执行。(以上代码使用的是默认TaskScheduler)

技术分享

TaskScheduler很可能马上执行,也有可能在未来的某一个特定时间点进行执行,取决于调度算法,以及CPU资源等。

三、Task的完成

刚开始说了。Task编程使用的是Master/Worker模式,该模式中最后一点是Worker最终会将结果返回给Master。由Master统一将结果进行汇总。在Task编程中有两个方法:

  1. Task.WaitAll。等待所有的Task(worker)完成。
  2. Task.WaitAny,等待任何一个Task完成即可。

3.1 Task.WaitAll

上面2.2的代码中已经使用了WaitAll,该方法将会等待两个Action完成之后才会进行返回,将上面的方法做一点改变。

class TaskDemo
    {
        public void Action1()
        {
            Thread.Sleep(1000);
            Console.WriteLine("in action1");
        }

        public void Action2()
        {
            Thread.Sleep(3000);
            Console.WriteLine("in action2");
        }

        public void StartTasks()
        {
            var task1 = Task.Factory.StartNew(Action1);
            var task2 = Task.Factory.StartNew(Action2);
            Task.WaitAll(task1, task2);
            Console.WriteLine("Finished");
        }
    }

WaitAll之后再打印出”Finished“,按照WaitAll的定义,Finished永远是最后打印出来的字符串。

技术分享

3.2 Task.WaitAny

将上面代码的WaitAll修改成WaitAny

       public void StartTasks()
        {
            var task1 = Task.Factory.StartNew(Action1);
            var task2 = Task.Factory.StartNew(Action2);
            Task.WaitAny(task1, task2);
            Console.WriteLine("Finished");
        }

最终运行结果:

技术分享

可以看出使用了WaitAny后,没有等待Task2执行完毕,程序就回到了主线程,先打印出了Finished。

四、取消Task

4.1 取消流程

Task取消使用一个叫做coorperative cancellation的模型进行Task取消。主要使用CancellationTokenSource完成。该对象有一个CancellactionToken。当StartNew一个Task时候,可以将toker传给被创建的task。当CancellationTokenSource调用Cancel后,Task对应的Token状态将会变为取消(Canceled),Task的状态也会变为取消。这时候如果Task还没有启动,Task将不会再执行任务。

 技术分享

当然最后在每个Task内部也对Token进行判断,如果token已经取消,则不再执行当前Action(有些task可能在CancellactionToke被取消之前已经启动了),修改一下执行图:

技术分享

4.2 演示代码

   class TaskDemo
    {
        public void Action1(CancellationTokenSource cts)
        {
            if(cts.IsCancellationRequested)
            {
                return;
            }
            Console.WriteLine("in action1");
        }

        public void Action2(CancellationTokenSource cts)
        {
            Thread.Sleep(2000);
            if (cts.IsCancellationRequested)
            {
                Console.WriteLine("action2 is canceled");
                return;
            }
            Console.WriteLine("in action2");
        }

        public void StartTasks()
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            var task1 = Task.Factory.StartNew(() => Action1(cts), cts.Token);
            var task2 = Task.Factory.StartNew(() => Action2(cts), cts.Token);
            Task.WaitAny(task1, task2);
            cts.Cancel();
            Console.WriteLine("Finished");
        }
    }

4.3 运行结果

技术分享

上面的运行结果有可能“action2 is canceled"这句话不会打印出来,因为有可能在Task2执行之前cts已经取消了。会进入流程图中第一个If判断点==》Not will run task

Parallel Programming-Task Base

标签:

原文地址:http://www.cnblogs.com/kmpp/p/Parallel_Programming_Task_Base.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!