Как развернуть Task <IEnumerable> для работы с результатами?

c# async-await

468 просмотра

3 ответа

Я настраиваю Task[]массив, чтобы я мог использовать Task.WhenAll()так:

Task[] tasks = new Task[2];

        tasks[0] = _widgetDataService.RetrieveAsync<CollaboratorNetworkNode>(
            "get_collaborator_nodes", portfolio,
            recentFys, nodesSwitch);

        tasks[1]  = _widgetDataService.RetrieveAsync<CollaboratorNetworkEdge>(
            "get_collaborator_edges", portfolio, recentFys);

        await Task.WhenAll();

Код работает нормально и доходит до точки останова Task.WhenAll.

Но теперь я иду, чтобы запустить этот код:

var nodes = from pi in (IEnumerable<CollaboratorNetworkNode>)tasks[0]
                    select new GraphNode { Id = pi.ProfileId, Properties = pi, Labels = new[] { "Person" } };

и я получаю сообщение об ошибке:

Невозможно привести объект типа 'System.Threading.Tasks.Task'1 [System.Collections.Generic.IEnumerable'1 [Nete.Ireport.Models.ViewModels.CollaboratorNetworkNode]]' для типа 'System.Collections.Generic.IEnumerable'. 1 [Nete.Ireport.Models.ViewModels.CollaboratorNetworkNode]».

Если я попытаюсь просто запустить это:

var nodes = from pi in tasks[0]
                    select new GraphNode { Id = pi.ProfileId, Properties = pi, Labels = new[] { "Person" } };

Я не могу скомпилировать, потому что я получаю красный волнистый с:

Задача не содержит определения для Select и наилучшего метода расширения перегрузки "DynamicQueryable.Select (IQueryable, string, params object [] требует приемник типа IQueryable.

Мы просто пытаемся запустить эти две службы извлечения, каждая из которых длится 10 секунд. Итак, наш звонок 20 секунд. Я достигаю точки разрыва сейчас через 13-15 секунд. Так что, если я смогу заставить это работать, я сбрил 5-7 секунд.

Но я не знаю, как использовать результаты.

Как я могу закончить этот метод?

Автор: Sam Источник Размещён: 08.11.2019 11:26

Ответы (3)


1 плюс

Вам нужно передать массив задач WhenAllметоду:

await Task.WhenAll(tasks);

Затем вы можете сохранить результаты, используя Resultсвойство:

var result1 = (Task[0] as Task<IEnumerable<CollaboratorNetworkNode>>).Result;
var result2 = (Task[1] as Task<IEnumerable<CollaboratorNetworkEdge>>).Result;

Измените приведенное выше на любой тип возвращаемого значения методов, которые вы вызываете асинхронно.

Примечание: используйте Task.Resultочень осторожно, если Taskоно еще не завершено.

Автор: Zein Makki Размещён: 20.08.2016 02:44

0 плюса

Это объявление вашего массива, которое вызывает проблему. Как предложил Харальд, ему следует использовать соответствующий Task<T>тип, а не отбрасывать информацию о типе с помощью Task:

var tasks = new Task<IEnumerable<CollaboratorNetworkNode>>[2];
tasks[0] = _widgetDataService.RetrieveAsync<CollaboratorNetworkNode>(
        "get_collaborator_nodes", portfolio,
        recentFys, nodesSwitch);
tasks[1]  = _widgetDataService.RetrieveAsync<CollaboratorNetworkEdge>(
        "get_collaborator_edges", portfolio, recentFys);
var results = await Task.WhenAll(tasks);
// results[0] is IEnumerable<CollaboratorNetworkNode>
// results[1] is IEnumerable<CollaboratorNetworkNode>

var nodes = from pi in results[0]
            select new GraphNode { Id = pi.ProfileId, Properties = pi, Labels = new[] { "Person" } };

Я рекомендую использовать результат, await Task.WhenAllкогда это возможно (как этот код делает). Если это невозможно (т. Е. Если задачи разных типов), то вы должны использовать awaitдля получения результатов, а не Result . Resultобернет любые исключения в AggregateException, что усложняет обработку ошибок.

Автор: Stephen Cleary Размещён: 23.08.2016 02:36

0 плюса

ваша функция _widgetDataService.RetrieveAsync<CollaboratorNetworkEdge>имеет возвращаемое значение, вероятно, типаTask<IEnumerable<CollaboratorNetworkNode>>

Вы не должны помещать эти возвращаемые значения в массив Task, но в массивTask<IEnumerable<CollaboratorNetworkNode>>

var tasks = new Task<IEnumerable<CollaboratorNetWorkNode>>[][2];
tasks[0] = _widgetDataService.RetrieveAsync<CollaboratorNetworkNode>(
        "get_collaborator_nodes", portfolio,
        recentFys, nodesSwitch);

tasks[1]  = _widgetDataService.RetrieveAsync<CollaboratorNetworkEdge>(
        "get_collaborator_edges", portfolio, recentFys);
await Task.WhenAll(tasks);
var nodes = tasks[0].Result.Select(pi=> new GraphNode
{
    Id = pi.ProfileId,
    ...
})
Автор: Harald Coppoolse Размещён: 22.08.2016 08:55
Вопросы из категории :
32x32