27.5 任务

Posted kikyoqiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了27.5 任务相关的知识,希望对你有一定的参考价值。

27.5.1 等待任务完成并获取结果

        static void Main(string[] args)
        {
            Task<int> task = new Task<int>(n => Sum((int)n), 10000);
            task.Start();
            task.Wait();
            Console.WriteLine($"sum is {task.Result}");
            Console.ReadKey();
        }
        private static int Sum(int n)
        {
            int sum = 0;
            for (; n > 0; n--)
            {
                checked
                {
                    sum += n;
                }
            }
            return sum;
        }

27.5.2 取消任务

        private static int Sum(CancellationToken token, int n)
        {
            int sum = 0;
            for (; n > 0; n--)
            {
                token.ThrowIfCancellationRequested();
                checked
                {
                    sum += n;
                }
            }
            return sum;
        }

 

        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            Task<int> t = Task.Run(() => Sum(cts.Token, 100000), cts.Token);
            cts.Cancel();
            try
            {
                Console.WriteLine("the sum is " + t.Result);
            }
            catch (AggregateException ex)
            {
                ex.Handle(e => e is OperationCanceledException);
                Console.WriteLine("sum was canceled");
            }
            Console.ReadKey();
        }
        private static int Sum(CancellationToken token, int n)
        {
            int sum = 0;
            for (; n > 0; n--)
            {
                token.ThrowIfCancellationRequested();
                checked
                {
                    sum += n;
                }
            }
            return sum;
        }

27.5.3 任务完成时自动启动新任务

        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            Task<int> t = Task.Run(() => Sum(cts.Token, 100), cts.Token);
            Task cwt = t.ContinueWith(task => Console.WriteLine("sum result is " + t.Result));
            Console.ReadKey();
        }
        private static int Sum(CancellationToken token, int n)
        {
            int sum = 0;
            for (; n > 0; n--)
            {
                token.ThrowIfCancellationRequested();
                checked
                {
                    sum += n;
                }
            }
            return sum;
        }

 

        static void Main(string[] args)
        {
            Task<int> t = Task.Run(() => Sum(100));
            t.ContinueWith(task => Console.WriteLine("sum result is " + t.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
            t.ContinueWith(task => Console.WriteLine("sum throw  " + t.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted);
            t.ContinueWith(task => Console.WriteLine("sum was cancel"), TaskContinuationOptions.OnlyOnCanceled);
            Console.ReadKey();
        }
        private static int Sum(int n)
        {
            int sum = 0;
            for (; n > 0; n--)
            {
                checked
                {
                    sum += n;
                }
            }
            return sum;
        }

27.5.4 任务可以启动子任务

        static void Main(string[] args)
        {
            Task<int[]> patientTask = new Task<int[]>(() =>
            {
                var results = new int[3];
                new Task(() => results[0] = Sum(100), TaskCreationOptions.AttachedToParent).Start();
                new Task(() => results[1] = Sum(200), TaskCreationOptions.AttachedToParent).Start();
                new Task(() => results[2] = Sum(300), TaskCreationOptions.AttachedToParent).Start();
                return results;
            });
            var cwt = patientTask.ContinueWith(patient => Array.ForEach(patient.Result, Console.WriteLine));
            patientTask.Start();
            Console.ReadKey();
        }
        private static int Sum(int n)
        {
            int sum = 0;
            for (; n > 0; n--)
            {
                checked
                {
                    sum += n;
                }
            }
            return sum;
        }

 27.5.6 任务工厂

        static void Main(string[] args)
        {
            Task patient = new Task(() =>
            {
                var cts = new CancellationTokenSource();
                var tf = new TaskFactory<int>(cts.Token,
                    TaskCreationOptions.AttachedToParent,
                    TaskContinuationOptions.ExecuteSynchronously,
                    TaskScheduler.Default);

                //这个任务创建并启动3个任务
                var childTasks = new[]
                {
                    tf.StartNew(()=>Sum(cts.Token, 100)),
                    tf.StartNew(()=>Sum(cts.Token, 200)),
                    tf.StartNew(()=>Sum(cts.Token, int.MaxValue))   //太大抛异常
                };

                //任何子任务抛出异常,就取消子任务
                for (int task = 0; task < childTasks.Length; task++)
                {
                    childTasks[task].ContinueWith(t => cts.Cancel(), TaskContinuationOptions.OnlyOnFaulted);
                }

                //所有子任务完成后,从未出错的/未取消的子任务获取返回最大值
                //将最大值传给另一个任务来显示最大值结果
                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);
            });

            //子任务完成后,也显示任何未处理的异常
            patient.ContinueWith(p =>
            {
                StringBuilder sb = new StringBuilder("The following exception(s) occurred:" + Environment.NewLine);
                foreach (var e in p.Exception.Flatten().InnerExceptions)
                    sb.AppendFormat(" {0}", e.GetType()).AppendLine();
                Console.WriteLine(sb.ToString());
            }, TaskContinuationOptions.OnlyOnFaulted);

            //启动父任务,使它能启动子任务
            patient.Start();

            Console.ReadKey();
        }
        private static int Sum(CancellationToken token, int n)
        {
            int sum = 0;
            for (; n > 0; n--)
            {
                checked
                {
                    sum += n;
                }
            }
            return sum;
        }

 

以上是关于27.5 任务的主要内容,如果未能解决你的问题,请参考以下文章

27.5 API中类型的变通使用

27.5 API中类型的变通使用

译文:18个实用的JavaScript代码片段,助你快速处理日常编程任务

林俊杰向B站up主索赔27.5万,背后的这种技术让人害怕

VS2015 代码片段整理

Android 片段生命周期