zoukankan      html  css  js  c++  java
  • 任务---内部揭秘

    1,Task对象都有一组字段,这些字段构成了任务的状态:

    id----任务的唯一标识

    可以使用 Task.CurrentId 静态属性来查询 当前正在调试的代码的ID.

    Status:

    Created:任务显示创建

    WaitingForActivation:任务通过ContinueWith函数创建.会自动开始

    WaitingToRan,任务正在调度,但是未执行

    Running,任务正在执行

    WaitingForChildrenToComplete:正在等待其子进程完成后才能完成.

    (设置TaskCreationOption.AttachedToParent)

    最终是以下三个状态之一

    RanToCompletion

    Canceled

    Faulted

    2,TaskFactory

     public static void TaskFactory()
            {
                Task parent = new Task(() =>
                {
                    var cts = new CancellationTokenSource();
                    var tf = new TaskFactory<Int32>(cts.Token, TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
    
                    // This tasks creates and starts 3 child tasks
                    var childTasks = new[] {
                tf.StartNew(() => Sum(cts.Token, 10000)),
                tf.StartNew(() => Sum(cts.Token, 20000)),
                tf.StartNew(() => Sum(cts.Token, Int32.MaxValue))  // Too big, throws OverflowException
             };
    
                    // If any of the child tasks throw, cancel the rest of them
                    for (Int32 task = 0; task < childTasks.Length; task++)
                        childTasks[task].ContinueWith(t => cts.Cancel(), TaskContinuationOptions.OnlyOnFaulted);
    
                    // When all children are done, get the maximum value returned from the non-faulting/canceled tasks
                    // Then pass the maximum value to another task which displays the maximum result
                    tf.ContinueWhenAll(childTasks,
                       completedTasks => completedTasks.Where(t => !t.IsFaulted && !t.IsCanceled).Max(t => t.Result),
                       CancellationToken.None)
                       .ContinueWith(t => Console.WriteLine("The maximum is: " + t.Result),
                          TaskContinuationOptions.ExecuteSynchronously).Wait(); // Wait is for testing only
                });
    
                // When the children are done, show any unhandled exceptions too
                parent.ContinueWith(p =>
                {
                    // I put all this text in a StringBuilder and call Console.WrteLine just once because this task 
                    // could execute concurrently with the task above & I don't want the tasks' output interspersed
                    StringBuilder sb = new StringBuilder("The following exception(s) occurred:" + Environment.NewLine);
                    foreach (var e in p.Exception.Flatten().InnerExceptions)
                        sb.AppendLine("   " + e.GetType().ToString());
                    Console.WriteLine(sb.ToString());
                }, TaskContinuationOptions.OnlyOnFaulted);
    
                // Start the parent Task so it can start its children
                parent.Start();
    
            }

            1,创建了一个任务工程,所有的子任务都是以相同方式配置.startNew 或者continuewith 的任务.都视为 TaskFactory的子任务.

          注意,TaskFactory返回一个任务数组.

            2,配置中,表示所有的子任务的父任务都是parent,包括continueWhenAll之类的.

           3,当调用cts.cancel()的时候,注意,为了不让后面的几个continueWhenAll函数取消调用 的 ConcellationToken.None来保证该

    Continue不被取消(因为在TaskFactory里面设置了取消,如果默认的话,这个Continue会被取消掉).

           4,AttachParent 和 ExecuteSynchronously()的区别.

             前者一般实在线程创建的时候,表示父线程必须要等待子线程全部完成后才算完成.

             后者表达了该线程的延续任务(ContinueWith)任务,在本来任务的线程上执行就是在同一个线程上面执行.

            上面表达的意思是,子任务的后续任务跟子任务使用同一个线程.

    3,任务调度器

               TaskScheduler.Default:使用线程池

              TaskScheduler.FromCurrentSynchronizationContext 获得一个同步的上下文调度器的使用,可以用来在Form程序中方便的

    在异步线程中更新UI界面.否则需要使用Invoke的方式:

    4,微软实列代码地址https://docs.microsoft.com/zh-cn/samples/browse/?redirectedfrom=MSDN-samples

    5,https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff963552(v=pandp.10)

    使用Parallel.For进行循环任务

          Parallel.ForEach 来进行迭代任务

          Parallel.Invoke进行多个方法执行.

    Parallel方法都接受一个ParallelOption参数:

     public class ParallelOptions
        {
            public ParallelOptions() { }
            public CancellationToken CancellationToken { get; set; }
            public Int32 MaxDegreeOfParallelism { get; set; }//最大线程数,默认=-1,为cpu的数量
    
            public TaskScheduler TaskScheduler { get; set; }
        }

    另外其还支持3个委托函数协助处理

     public static Int64 DirectoryBytes(string path, string searchPattern, SearchOption searchOption)
            {
                var files = Directory.EnumerateFiles(path, searchPattern, searchOption);//枚举所有的文件.
                Int64 mastertotals = 0;//累计全部bytes
    
                ParallelLoopResult result = Parallel.ForEach<String, Int64>(
                    files,//tsource---需要处理的迭代对象.
                    () =>0,//Tlocal---每个初始化值,传递给body.
    
                    (file, loopState, taskLocalTotal) =>//处理函数,file是tsource的一个,loopstate是循环控制对象,taskLocakTotal是第一个
                    //函数传递下来TLocal的初始值.用于给body使用.
                    {
                        Int64 fileLength = 0;
                        FileStream fs = null;
                        try
                        {
                            fs = File.OpenRead(file);
                            fileLength = fs.Length;
                        }
                        catch (IOException) { }
                        finally
                        {
                            if (fs != null) fs.Dispose();
    
                        }
                        return taskLocalTotal + fileLength;
                    },
                    taskLocalTotal =>//这个参数是body函数的返回值,传递给Finally函数.Initial->Body->Finally.
                    {
                        Interlocked.Add(ref mastertotals, taskLocalTotal);//安全的进行数据操作.
                    }
    
                    );
                return mastertotals;//返回值.
            }

      1,该函数的原型:

    ParallelLoopResult ForEach<TSource,TLocal> (

    IEnumerable<TSource> source, Func<TLocal> localInit,

    Func<TSource,System.Threading.Tasks.ParallelLoopState,long,TLocal,TLocal> body,

    Action<TLocal> localFinally);

    2,ParallelLoopResult

    IsCompleted
    获取该循环是否已运行完成(即,该循环的所有迭代均已执行,并且该循环没有收到提前结束的请求)。
    LowestBreakIteration
    获取从中调用 Break() 的最低迭代的索引。

    3,三个委托之间的关系:

               Func<TLocal>:用于初始化一个本地对象.

              Func<TSource,System.Threading.Tasks.ParallelLoopState,long,TLocal,TLocal> body,

              用于处理对象,

                     Tsource:处理源

                     ParallelLoopState:状态控制字

                               属性:IsExceptional:是否发生异常

                                      IsStopped : 是否调用Stop方法//会触发ShouldExit

                                     LowestBreakIteration:最低调用break的迭代

                                     ShouldExitCurrentIteration:

                                                 在调用了break,stop或者异常,或者ParallelOption中的CancellationToken也会为true

                                  stop();立即停止处理项

                                  break();在处理完当前项后,尽快停止处理项.(保证处理完当前项)但是不保证该项是最后处理的项.所以,LowestBreakIteration保存了最低处理的项.

        4,可通过检查结果来了解:

                     如果complete=true ,则表明完成

                           如果LowestBreakIteration!=null则表明在某项调用了break

                           =null,则表明调用了stop方法.如果抛出异常,应该捕捉AggregateException来得体的恢复.

  • 相关阅读:
    Base64字符串在传递过程中加号被转成空格
    IIS无法启动,应用程序池自动关闭,应用程序池XXXX将被自动禁用 解决方案之一
    我要写程序我要写程序
    react native项目改名(仅针对android)
    webpack之html-webpack-plugin的使用
    webpack之React开发环境配置
    webpack之webpack-dev-server的使用
    html2canvas截图空白问题
    webpack源码分析——参数初始化
    webpack源码分析——配置调试环境
  • 原文地址:https://www.cnblogs.com/frogkiller/p/12465779.html
Copyright © 2011-2022 走看看