.Net 并行计算 ----并行任务_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > .Net 并行计算 ----并行任务

.Net 并行计算 ----并行任务

 2013/12/23 17:09:06  Wang.Crystal  博客园  我要评论(0)
  • 摘要:本文作为.Net并行计算的第二篇名词解释任务并行是指一个或者多个独立的任务同时运行。任务并行类似于多线程或者ThreadPool工作项。但是抽象的级别更高并行任务的2个有点1。系统使用的率更高2.可以使用更多的编程控件创建和运行任务1.隐式创建和运行任务。Parallel.Invoke方法提供了一种简便方式,可同时运行任意数量的任意语句。只需为每个工作项传入Action委托即可大家可以想一下了例子的运行结果是什么?会是输出时间2000吗。如果你这么想就错了。笔者的电脑上输出的结果为时间1005
  • 标签:.net 并行计算 net

本文作为 .Net 并行计算 的第二篇

 
  • 名词解释

       任务并行是指一个或者多个独立的任务同时运行。任务并行类似于多线程或者ThreadPool 工作项。但是抽象的级别更高

  •  并行任务的2个有点 1。系统使用的率更高 2.可以使用更多的编程控件
  • 创建和运行任务

       1.隐式创建和运行任务。Parallel.Invoke方法提供了一种简便方式,可同时运行任意数量的任意语句。class="sentence" data-source="Just pass in an <span><span class="mtpsTagOuterHtml" ><span>Action</span></span></span> delegate for each item of work." data-guid="8f6bd07894e8b7e41bf35baf174af946">只需为每个工作项传入 Action 委托即可 大家可以想一下了例子的运行结果是什么? 会是输出 时间2000 吗 。如果你这么想就错了。笔者的电脑上输出的结果为 时间1005 (可能在你的电脑上的结果和我一定相同)因为他并不是一个顺序执行的过程。

            Stopwatch watch1 = Stopwatch.StartNew();
Parallel.Invoke(() => { Thread.Sleep(1000); }, () => { Thread.Sleep(1000); }); Console.WriteLine("时间"+watch1.ElapsedMilliseconds);

     2.显示创建和运行任务

       不返回值的任务由 System.Threading.Tasks.Task 类表示。返回值的任务由 System.Threading.Tasks.Task<TResult>类表示,该类从Task继承thread throughout the lifetime of the task." data-guid="18a45a50d09d2acd703988bfae80c515">任务对象处理基础结构详细信息,并提供可在任务的整个生存期内从调用线程访问的方法和属性。下面的例子演示创建一个不返回的任务,和一个返回值的任务

      

            var task = new Task(() => { Thread.Sleep(1000); });
            task.Start();
            var task1 = new Task<int>(() => { Thread.Sleep(1000); return 100; });
            task1.Start();
            Console.WriteLine(task1.Result);
            Console.ReadLine();
  •  延续任务

        我们经常会面对这样一个场景。在一个操作完成后调用另一个的操作并将结果传递其中,我们日常编程中我们一般使用回调来弄。那么我们要怎么样在并行中来处理这个场景了。并行库中的“延续任务”提供了同样功能。  延续任务是一个异步任务,由另一个任务(称为前面的任务)在完成时调用。  下面的例子将使用TaskA.ContinueWith演示创建延续

            Task<int> TaskA = new Task<int>(() => { return DateTime.Now.Year; });
            Task<String> TaskB = TaskA.ContinueWith((a) => { return String.Format("今年是{0}年", a.Result); });
            TaskA.Start();
            Console.WriteLine(TaskB.Result);

     在上面这个例子中TaskB 必须要TaskA 完成之后。才能得到正确结果。这只是延续的一个非常简单的例子,当然你也可以创建一个多任务延续你可以在多个,或者全部的任务完成之后来运行 这里我还是以上面的取消年月为例子给大家演示一下
        

   Task<int>[] tasks = new Task<int>[2];
             tasks[0]= new Task<int>(() => { return DateTime.Now.Year; });
             tasks[1] = new Task<int>(() => { return DateTime.Now.Month; });
             var continuation = Task.Factory.ContinueWhenAll(
                                  tasks,
                                  (antecedents) =>
                                  {
                                      string r = string.Format("现在是{0}年{1}月", antecedents[0].Result, antecedents[1].Result);
                                      Console.WriteLine(r);
                                  });
             tasks[0].Start();
             tasks[1].Start();
             continuation.Wait();
  •  嵌套任务和子任务

        子任务(或嵌套任务)是在另一个任务(称为父任务)的用户委托中创建的Task实例。 can be either detached or attached." data-guid="89104384ea0ee16afe06c677457eb3a5">子任务可分离或附加。  分离的子任务是独立于其父任务执行的任务。  created with the <span><span class="mtpsTagOuterHtml" ><span>TaskCreationOptions<span class="mtpsTagOuterHtml" xmlns=""><span>.</span></span>AttachedToParent</span></span></span> option." data-guid="85c3ce7207b7cb832ff59c3be81907d2">附属子任务是使用 TaskCreationOptions.AttachedToParent 选项创建的嵌套任务。  system resources." data-guid="6ca421e8fc40dce9102a5f7b71c3aeb2">一个任务可以创建任意数量的嵌套和分离子任务,该数量仅受系统资源限制

 var parent = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("父任务");

                var child = Task.Factory.StartNew(() =>
                {

                    Thread.Sleep(5000);
                    Console.WriteLine("子任务");
                });
            });

            parent.Wait();
            Console.WriteLine("大家都完了.");

   大家想不想知道,上面的执行结果是怎么样了 "父任务 子任务 大家都完了" 还是“父任务  大家都完了 子任务" 你可以把这段代码考到vs中,你就会发现是后者从上面的例子中我们可以得出以下结论 父任务是不等待子任务完成的  他还有以下特性 父任务不传播子任务引发的异常。父级状态不依赖于子状态。

  • 任务取消

     1.简单从委托中返回。其实在多数情况下这样已经够了。但是这样取消的任务实例不会转为Canceled状态而是转为RanToCompletion状态

     2.引发 OperationCanceledException 

    

           var tokenSource = new CancellationTokenSource();
            CancellationToken ct = tokenSource.Token;

            var task = Task.Factory.StartNew(() =>
            {
                ct.ThrowIfCancellationRequested();
            
            bool moreToDo=true;
            while (moreToDo)
            {
                if (ct.IsCancellationRequested)
                {
                    ct.ThrowIfCancellationRequested();
                }
            }

            }, tokenSource.Token);

            tokenSource.Cancel();
            try
            {
                task.Wait();
            }
            catch (AggregateException e)
            {
                foreach (var v in e.InnerExceptions)
                    Console.WriteLine(e.Message + " " + v.Message);
            }


   下一篇将讲一下并行Linq 欢迎交流拍砖

   

 

 

         

  

发表评论
用户名: 匿名