【发布时间】:2016-05-02 21:17:33
【问题描述】:
我需要修改一个现有程序,它包含以下代码:
var inputs = events.Select(async ev => await ProcessEventAsync(ev))
.Select(t => t.Result)
.Where(i => i != null)
.ToList();
但这对我来说似乎很奇怪,首先在选择中使用async和await。根据斯蒂芬克利里的this answer,我应该可以放弃这些。
然后是第二个Select,它选择了结果。这是否意味着任务根本不是异步的并且是同步执行的(付出了这么多的努力白费了),或者任务将异步执行并且当它完成时执行其余的查询?
我是否应该按照another answer by Stephen Cleary 编写上面的代码:
var tasks = await Task.WhenAll(events.Select(ev => ProcessEventAsync(ev)));
var inputs = tasks.Where(result => result != null).ToList();
和这个完全一样吗?
var inputs = (await Task.WhenAll(events.Select(ev => ProcessEventAsync(ev))))
.Where(result => result != null).ToList();
虽然我正在处理这个项目,但我想更改第一个代码示例,但我不太热衷于更改(显然可以工作)异步代码。也许我只是无所顾忌,所有 3 个代码示例都做同样的事情?
ProcessEventsAsync 看起来像这样:
async Task<InputResult> ProcessEventAsync(InputEvent ev) {...}
【问题讨论】:
-
ProceesEventAsync 的返回类型是什么?
-
@tede24
Task<InputResult>InputResult是一个自定义类。 -
在我看来,您的版本更容易阅读。但是,您忘记了
SelectWhere之前的任务结果。 -
而且 InputResult 有一个 Result 属性对吗?
-
对于懒惰的开发者来说,还有一种方法可以使这段代码异步。只需添加
ToList()以创建所有任务,然后等待events.Select(async ev => await ProcessEventAsync(ev)).ToList().Select(t => t.Result)...这样的结果。与WaitAll()相比,这对性能有轻微影响,但在大多数情况下可以忽略不计。
标签: c# linq asynchronous