第26章 计算限制的异步操作(8)

本文深入探讨了Task对象的工作原理,包括其唯一ID的生成机制、状态管理、异常处理及如何使用任务工厂(TaskFactory)创建任务。介绍了TaskStatus枚举的各种状态及含义,并解释了如何通过Task的Boolean属性简化编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

26.5.5 任务内部揭秘

在每个Task对象中,都包含代表Task唯一ID的一个Int32字段。创建一个Task对象时,字段初始化为零。第一次查询Task的只读Id属性时,属性将一个唯一Int32值分配给该字段,并从属性中返回它。TaskID从1开始,每分配一个ID都递增1。这个ID的意义在于,每个Task都可以用一个唯一的值来标识。运行一个任务的代码时,可以查询Task的静态CurrentId属性,它返回一个可空Int32(Int32?)。如果当前没有任务正在执行,查询CurrentId属性会返回null。

一个Task对象存在期间,可查询Task的只读Status属性了解它在其生存期的什么位置。这个属性返回一个TaskStatus值。TaskStatus值:Created、WaitingForActivation、WaitingToRun、Running、WaitingForChildrenToComplete、RanToCompletion、Canceled、Faulted。

一个Task或者Task<TResult>出错时,可以查询Task的Exception属性来获得任务抛出的未处理的异常。该属性总是返回一个AggregateException对象,它的包含了所有未处理的异常。

为简化编码,Task提供了几个只读的Boolean属性:IsCanceled、IsFaulted和IsCompleted。

如果Task是通过以下某个函数来创建的,这个Task对象就会处于WaitForActivation状态:ContinueWith、ContinueWhenAll、ContinueWhenAny或者FromAsync。

不能显式启动一个通过调用ContinueWith来创建的对象,这个Task会在它的先驱任务(antecedent task)执行完毕后自动开始。

26.5.6 任务工厂

如果要创建的是一组没有返回值的任务,那么要构造一个TaskFactory;如果要创建的是一组有一个特定返回值的任务,那么要构造一个TaskFactory<TResult>,并通过泛型TResult实参来传递任务的返回类型。创建任何工厂类时,要向它的构造器传递一些默认值。工厂创建的任务都将具有这些默认值。具体地说,要向任务工厂传递你希望工厂创建的任务具有的CancellationToken,TaskScheduler,TaskCreationOptions和TaskContinuationOptions设置。

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ThreadStudy
{
    class Program
    {
        static void Main(string[] args)
        {
            Task tp = new Task(() =>{
                var cts = new CancellationTokenSource();
                var tf = new TaskFactory<int>(cts.Token, TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
                var childTasks = new[]{
                tf.StartNew(()=>Sum(cts.Token,100)),
                tf.StartNew(()=>Sum(cts.Token,10)),
                tf.StartNew(()=>Sum(cts.Token,10000))
                };

                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);
            });
            tp.Start();
            Thread.Sleep(3000);
        }

        static int Sum(CancellationToken ct, int num)
        {
            ct.ThrowIfCancellationRequested();
            if (num == 0)
                return 0;
            else
                return num + Sum(ct, num - 1);
        }
    }
}
无论先驱任务是如何完成的,ContinueWhenAll和ContinueWhenAny都会执行延续任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值