任务中的对象声明<> [] Task.Factory.ContinueWhenAll

时间:2010-08-11 11:20:03

标签: c#-4.0

   var t1 = Task.Factory.StartNew(() => test<Employee>());
    var t2 = Task.Factory.StartNew(() => test<Customer>());
    var t3 = Task.Factory.StartNew(() => test<Order>());

    Task[] tasks = new Task[] { t1, t2, t3 };

    var resultx = Task.Factory.ContinueWhenAll(tasks, (task) =>
    {
        Task.WaitAll();
        task[0]// Result is missing, I don't see Result in the intellisense.
    }
   );

看来,如果我在Task<T>任务中提到数据类型,那么我就能看到像task[0].Result这样的智能感知中弹出“结果”。为什么会这样? 。 每个测试方法返回一个作为泛型项传递的IEnumerable<T>类型的对象。实际上,我传递给test<T>()的所有对象都继承自基类“公司”。基本上是一个抽象的工厂模式。我是遗失了什么?

1 个答案:

答案 0 :(得分:3)

基类Task类没有Result属性。该属性在Task<TResult>上定义,{{3}}是Task的子类。如果test<T>()返回IEnumerable<T>,则t1,t2和t3的类型为Task<IEnumerable<Employee>>Task<IEnumerable<Customer>>Task<IEnumerable<Order>>。由于这些都是Task的子类,因此将它们添加到Task数组中是完全合法的。然后,您调用ContinueWhenAll的重载,该重载采用Task个对象的数组,因此您将无法使用Task<TResult>上的方法。

如果员工,客户和订单都从公司继承,那么您可以创建一个Task<IEnumerable<Company>>个对象的数组,并使用ContinueWhenAll的重载,其中包含Task<TResult>数组。

由于Task<IEnumerabl<Employee>>不是协变的,您将无法将Task<IEnumerable<Company>>投放到Task,但您可以首先将其创建为Task<IEnumerable<Company>>

这样的事情:

var t1 = Task.Factory.StartNew<IEnumerable<Company>>(() => test<Employee>());
var t2 = Task.Factory.StartNew<IEnumerable<Company>>(() => test<Customer>());
var t3 = Task.Factory.StartNew<IEnumerable<Company>>(() => test<Order>());

var tasks = new Task<IEnumerable<Company>>[] { t1, t2, t3 };

var resultx = Task.Factory.ContinueWhenAll(tasks, (task) =>
{
    IEnumerable<Company> result = task[0].Result;
});

另一种选择是直接使用t1,t2和t3变量而不是使用任务参数。 task参数将包含与原始任务数组相同的对象,因此您可以这样做:

var resultx = Task.Factory.ContinueWhenAll(tasks, (task) =>
{
    IEnumerable<Employee> result = t1.Result;
});