zoukankan      html  css  js  c++  java
  • (CLR via C#学习笔记)任务和并行操作

    一 任务

        可以调用ThreadPool的QueueUserWorkItem方法发起一次异步的计算限制操作.
    但这个技术有很多限制.最大的问题是没有内建的机制让你知道操作在什么时候
    完成和操作完成时的返回值.为了克服这些限制(并解决其他一些问题),Microsoft
    引入了任务的概念.

    1  //调用QueueUserWorkItem
    2 ThreadPool.QueueUserWorkItem(DoSomeThing, 5);
    3 
    4 //用任务来做相同的事情
    5 Task.Run(() => DoSomeThing(5));      

    二 任务抛出异常

        如果计算限制的任务抛出未处理的异常,异常会被"吞噬"并存储到一个集合中,
    而线程池线程可以返回到线程池中.调用Wait方法或者Result属性时,这些成员
    会抛出一个System.AggregateException对象.

    三  取消任务

        调用CancellationToken的ThrowIfCancellationRequested,如果CancellationToken
    已经取消,任务将会抛出OperationCanceledException.之所以选择抛出异常,是因为
    和ThreadPool的QueueUserWorkItem方法初始化的工作项不同,任务有办法表示完成,
    任务甚至能返回一个值.所以,采取一种方式将已完成的任务和出错的任务区分开.
    而让任务抛出异常,就可以知道任务没有一直运行到结束.

     1 CancellationTokenSource cts = new CancellationTokenSource();
     2 Task<int> t = Task.Run<int>(() => Sum(cts.Token, 2000));
     3 Thread.Sleep(10);
     4 cts.Cancel();
     5 
     6 try
     7 {
     8     Console.WriteLine("The Sum is: " + t.Result);
     9 }
    10 catch (AggregateException x)
    11 {
    12     //将任何OperationCanceledException对象都视为已处理
    13     //使其中只包含未处理的异常
    14      x.Handle(e => e is OperationCanceledException);
    15 
    16     //对未处理的异常进行处理
    17     //TODO
    18     //...
    19     //...
    20 
    21     Console.WriteLine("Sum was canceled");
    22 }
     1 static int Sum(CancellationToken ct,int n)
     2 {
     3     if (n > 1000)
     4     {
     5         throw new Exception("Value of n is too large.");
     6     }
     7 
     8     int sum = 0;
     9     for (int i = 1; i <= n; i++)
    10     {
    11         //如果CancellationTokenSource已取消(Cancel),
    12         //下面代码将抛出"System.OperationCanceledException"异常
    13         ct.ThrowIfCancellationRequested();
    14         sum += i;
    15     }
    16     return sum;
    17 }

    四 Parallel的静态For,ForEach和Invoke方法

    使用Parallel的方法一些前提条件:
    a.工作项必须能并行执行,如果工作必须顺序执行,就不要使用Paralle方法;
    b.工作项最好不要有修改共享数据的操作,否则多个线程同时处理共享数据,可能会算坏
    数据;
    c.每个工作项都涉及大量工作,那么使用Parallel方法产生的性能损失可以忽略不计;
    d.有大量可由多个线程同时处理的工作项,那么使用Parallel也许能获得性能的提升.

     1 //Parallel的For方法
     2 for (int i = 0; i < 1000; i++)
     3 {
     4     DoWork(i);
     5 }
     6 Parallel.For(0, 1000, i => DoWork(i));
     7 
     8 //Parallel的ForEach方法
     9 int[] idCollection = new int[] {1,2,3,4,5,6,7,8,9 };
    10 foreach (var item in idCollection)
    11 {
    12     DoWork(item);
    13 }
    14 Parallel.ForEach(idCollection, item => DoWork(item));
    15 
    16 //Parallel的Invoke方法
    17 Method1();
    18 Method2();
    19 Method3();
    20 Parallel.Invoke(
    21     () => Method1(),
    22     () => Method2(),
    23     () => Method3());

    五 定时计算限制操作(Timer)

    FCL提供了几个以下几种主要的定时器:
    a.System.Threading的Timer类
    要在一个线程池上执行定时的(周期性发生的)后台任务,它是最好的计时器.

    b.System.Timers的Timer类
    这个计时器本质上是System.Threading的Timer类的包装类,它允许在Visual
    Studio中的设计器更容易使用.
    建议不用这个计时器,除非真的想在设计平面上添加一个计时器.

    c.System.Windows.Forms的Timer类 

  • 相关阅读:
    Codeforces Round #605 (Div. 3)E
    Codeforces Round #628 (Div. 2)
    Codeforces Round #627 (Div. 3)
    AC自动机,知识点+hdu模板题
    Tire树,hdu2846,hdu4825
    Educational Codeforces Round 83 (Rated for Div. 2)
    分层最短路
    初入mysql的学习
    赛后总结
    Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round) D
  • 原文地址:https://www.cnblogs.com/miaosha5s/p/7113364.html
Copyright © 2011-2022 走看看