Объявление объекта в Task <> [] Task.Factory.ContinueWhenAll - PullRequest
0 голосов
/ 11 августа 2010
   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>, то смогу увидеть всплывающее окно "Результат" в значении intellisense, например task[0].Result. Почему это так? , Каждый тестовый метод возвращает IEnumerable<T> объект типа, переданный как универсальный элемент. Фактически, все объекты, которые я передаю test<T>(), наследуются от базового класса «Компания». В основном это абстрактный шаблон фабрики. Я что-то пропустил?

1 Ответ

3 голосов
/ 12 августа 2010

Базовый Task класс не имеет свойства Result. Это свойство определено в Task<TResult>, который является подклассом Task. Если test<T>() возвращает IEnumerable<T>, то t1, t2 и t3 имеют тип Task<IEnumerable<Employee>>, Task<IEnumerable<Customer>> и Task<IEnumerable<Order>>. Поскольку это все подклассы Task, совершенно законно добавить их в массив Task. Затем вы вызываете перегрузку ContinueWhenAll, которая принимает массив из Task объектов, поэтому вы не сможете использовать методы на Task<TResult>.

Если все Employee, Customer и Order наследуются от Company, вы можете вместо этого создать массив объектов 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 вместо использования параметра задачи. Параметр задачи будет содержать те же объекты, что и исходный массив задач, поэтому вы можете просто сделать:

var resultx = Task.Factory.ContinueWhenAll(tasks, (task) =>
{
    IEnumerable<Employee> result = t1.Result;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...