我正在尝试在另一个选择语句内的一个选择语句内等待异步操作。
var result = someList
.Select(table => new Table
{
Columns = table.Select(async column => new Column
{
Constraints = await GetColumnConstraints()
})
})
.ToList();
此处的“问题”是嵌套的select语句返回任务列表。通常,我们将使用Task.WhenAll()
等待所有任务。因此,最简单的方法是将列的类型从List<Column>
更改为List<Task<Column>>
,然后使用SelectMany()
来获取每个Task并等待它们。但是我无法更改列的数据类型。
我该如何实现?我找不到任何不涉及Task.WhenAll()
答案 0 :(得分:1)
显然Somelist
是Tables
的序列,其中每个Table
都有Columns
的序列。
在我看来,这些表的列不影响GetColumnConstraints()
。为什么每列调用一次此函数?如果只调用一次,会不会更有效率?
var columnConstraints = await GetColumnConstraintsAsync();
var result = tables.Select(table => new Table
{
Columns = table.Select(column => new Column
{
Constraints = columnConstraints,
...
})
})
.ToList();
可能是您简化了问题,而枚举的表和列确实会影响所获取的约束,例如,因为它们被用作输入变量。也许,如果您第二次调用该函数,则会遇到不同的约束条件?
如果您确实需要获取每个表的每个列的约束,则在创建表之前先等待获取约束:
var result = tables.Select(table =>
{
var columnTasks = table.Select(column => GetColumnContraintsAsync(...)).ToArray();
// all tasks are running now, wait until all are completed:
await Task.WhenAll(columnTasks);
// fetch the result from every task:
var columnTaskResults = columnTasks.Select(columnTask => columnTask.Result).ToList();
// create a Table with these results and return it:
return new Table
{
Columns = columnTaskResults,
};
})
.ToList();
答案 1 :(得分:1)
您不需要更改Column
的类型,只需要在表的初始值设定项之外await
即可。这样一来,您就可以在columnTasks
,await
中收集所有结果,然后创建新表。
var result = someList.Select(async table =>
{
var columnTasks = table.Select(async column => new Column()
{
Constraints = await GetColumnConstraints()
});
var columns = await Task.WhenAll(columnTasks);
return new Table()
{
Columns = columns
};
});
请注意,尽管async
沿链条向上发展,所以reuslt
现在是IEnumerable<Task<Table>>
,您必须await Task.WhenAll
才能获得{{ 1}}
Table