/// <summary>
 /// 第二十三章:使用任务提高吞吐量
 /// </summary>
 namespace Chapter23
 {
     class Program
     {
         static void Main(string[] args)
         {
             //23.1使用并行处理执行多任务处理
             /*
             * 多任务处理的原因:
             * 1.增强可响应性
             * 2.增强可伸缩性(减少执行所需要的时间)
             */
//23.2多核处理器的崛起(要最大化地利用多核处理器,必须在写程序时就想好怎么利用多任务处理。)
            //23.3用Microsoft.NET实现多任务处理(System.Threading.Tasks)
             ///23.3.1任务、线程和线程池
             /*
              * Task类是对一个并发操作的抽象
              *      桌面应用程序用System.Threading的Threading类
              *      UWP应用中使用Task类
              * 在单处理器上无区别,
              * 在多处理器上:
              *      线程数少于可用的处理器数量会造成CPU“欠饱和”,处理能力会浪费,
              *      如果多于可用处理器数量,或造成CPU“过饱和”以及较差的响应能力
              * 重点在于:将应用程序分解成可并行运行的任务。(WinRT会安排高效运行)
              */
             ///23.3.2创建、运行和控制任务
             /*
              * Task构造器有多个重载版本,但所有版本都要求提供一个Action委托作为参数。
              */
             Action<Object> action;
             action = doWorkWithObject;
             object parameterData = 1;
             Task task = new Task(action, parameterData);
             //创建好的对象用start方法启动
             task.Start();
             //由于要经常创建和运行任务,Task提供了Run合并两个操作
             Task task1 = Task.Run(() => doWorkWithObject(parameterData));
             //一个任务后延续另一个任务
             Task newTask = task.ContinueWith(doMoreWork);
             /*
              * ContinueWith方法有许多个重载版本
              * 其中一个指定了TaskCreationOptions的值(TaskCreationOptions是枚举,它包含了枚举值的一个超集)
              * 1.NotOnCanceled和OnlyOnCanceled
              *  NotOnCanceled指定上一个行动顺利完成,没有中途取消,延续任务才应该进行。
              *  OnlyOnCanceled指定上一个行动被取消的钱地下,延续任务才应该进行。
              * 2.NotOnFaulted和OnlyOnFaulted
              *  NotOnFaulted指定上一个行动顺利完成,没有抛出未处理的异常,延续任务才应该进行。
              *  OnlyOnFaulted指定只有上一个行动抛出未处理的异常,延续任务才应该进行。
              * 3.NotOnRanToCompletion和OnlyOnRanToCompletion
              *  NotOnRanToCompletion指定上一个行动没成功完成,延续任务才应该进行。
              *  OnlyOnRanToCompletion指定只有上一个行动成功完成,延续任务才应该进行。
              */
             task.ContinueWith(doMoreWork, TaskContinuationOptions.NotOnFaulted);
             //想好后面延续之后,后面再tack.start()
             task.Wait();//等待
             Task.WaitAll(task, task1);//等待task和task1都完成
             Task.WaitAny(task, task1);//等待task或task1都完成
                                       ///23.3.3使用Task类实现并行处理(略)
                                       ///23.2.4使用Parallel类对任务进行抽象
             /*
              * 1.cpu核心数不一样,每种情况的代码也不一样
              * 2.任务同步非常重要
              * 
              * 所以Parallel对编程构造进行“并行化”,任务完成时会自动同步。
              */
             //(1)Parallel.For
             Parallel.For(0, 100, performLoopProcessing);//相当于i=0;i<100;i++
             //利用这个方法的重载版本,可以提供对于每个线程来说都是私有的局部数据,以便将状态信息传给循环的其他并发迭代。
             //(2)Parallel.ForEach<T>
             //(3)Parallel.Invoke
             /*
              * 以并行任务的形式执行一组无参的方法。
              * 要指定无参且无返回值的一组委托方法调用。
              */
             Parallel.Invoke(
                 dowork,
                 doMoreWork
                 );
             ///23.2.5 什么时候使用Parallel类
             /*
              * 只有绝对必要时才使用,计算密集型的操作才使用
              * 前提是:并行操作必须独立!
              */
            //23.4 取消任务和处理异常
             /*
              * 粗暴地终止任务可能造成应用程序的数据处于不确定性
              * 使用task类实现的协作式取消,允许任务在方便时停止处理,并允许它在必要时撤销之前的工作
              */
             ///23.4.1协作式取消的原理
         }
        private static void dowork()
         {
             throw new NotImplementedException();
         }
        private static void doMoreWork()
         {
             throw new NotImplementedException();
         }
        private static void performLoopProcessing(int x)
         {
             throw new NotImplementedException();
         }
        private static void doMoreWork(Task obj)
         {
             throw new NotImplementedException();
         }
        /// <summary>
         /// task被创建时,将运行委托的指定的方法
         /// </summary>
         /// <param name="obj"></param>
         private static void doWorkWithObject(object obj)
             {
                 throw new NotImplementedException();
             }
     }
}
  
namespace Chapter23
 {
     /// <summary>
     /// 23.4.1 协作取消的原理
     /// </summary>
     class MyApplication
     {
         private void initiateTasks(){
             //创建CancellationTokenSource对象,并查询其Token属性来获得一个取消标志
             CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
             CancellationToken cancellationToken = cancellationTokenSource.Token;
             //创建一个任务,启动它来运行dowork方法
             Task myTask = Task.Run(() => doWork(cancellationToken));
             int i = 0;
             if (i == 0)//指定在什么情况下取消任务
             {
                 cancellationTokenSource.Cancel();//取消任务
             }
        }
        /// <summary>
         /// 这是由任务运行的方法
         /// </summary>
         /// <param name="token"></param>
         private static void doWork(CancellationToken token)
         {
             throw new NotImplementedException();
         }
     }
 }