我需要修改现有程序,它包含以下代码:
var inputs = events.Select(async ev => await ProcessEventAsync(ev))
.Select(t => t.Result)
.Where(i => i != null)
.ToList();
Run Code Online (Sandbox Code Playgroud)
但这对我来说似乎很奇怪,首先是使用async和await选择.根据Stephen Cleary的回答,我应该能够放弃这些.
然后第二个Select选择结果.这是不是意味着任务根本不是异步的并且是同步执行的(没有任何努力),或者异步执行任务,何时完成查询的其余部分?
我应该根据Stephen Cleary的另一个答案写下面的代码如下:
var tasks = await Task.WhenAll(events.Select(ev => ProcessEventAsync(ev)));
var inputs = tasks.Where(result => result != null).ToList();
Run Code Online (Sandbox Code Playgroud)
这是完全一样的吗?
var inputs = (await Task.WhenAll(events.Select(ev => ProcessEventAsync(ev))))
.Where(result => result != null).ToList();
Run Code Online (Sandbox Code Playgroud)
当我正在研究这个项目时,我想更改第一个代码示例,但我不太热衷于更改(显然工作)异步代码.也许我只是担心什么都没有,所有3个代码示例完全相同?
ProcessEventsAsync如下所示:
async Task<InputResult> ProcessEventAsync(InputEvent ev) {...}
Run Code Online (Sandbox Code Playgroud) 我有一个我创建的任务列表,如下所示:
public async Task<IList<Foo>> GetFoosAndDoSomethingAsync()
{
var foos = await GetFoosAsync();
var tasks = foos.Select(async foo => await DoSomethingAsync(foo)).ToList();
...
}
Run Code Online (Sandbox Code Playgroud)
通过使用.ToList(),任务都应该开始.现在我想等待完成并返回结果.
这适用于上面的...块:
var list = new List<Foo>();
foreach (var task in tasks)
list.Add(await task);
return list;
Run Code Online (Sandbox Code Playgroud)
它做我想要的,但这似乎相当笨拙.我宁愿写一些更简单的东西:
return tasks.Select(async task => await task).ToList();
Run Code Online (Sandbox Code Playgroud)
...但这不会编译.我错过了什么?或者是不可能以这种方式表达事物?
几乎每个SO关于这个主题的答案都表明:
另外:
但在斯蒂芬的书中有一个样本:
问题:您有一组要处理的任务,并且您希望在完成后对每个任务执行一些处理.但是,您希望在完成后立即对每个进行处理,而不是等待任何其他任务.
推荐的解决方案之一是:
static async Task<int> DelayAndReturnAsync(int val)
{
await Task.Delay(TimeSpan.FromSeconds(val));
return val;
}
// This method now prints "1", "2", and "3".
static async Task ProcessTasksAsync()
{
// Create a sequence of tasks.
Task<int> taskA = DelayAndReturnAsync(2);
Task<int> taskB = DelayAndReturnAsync(3);
Task<int> taskC = DelayAndReturnAsync(1);
var tasks = new[] { taskA, taskB, taskC };
var processingTasks = tasks.Select(async t =>
{
var result = await t;
Trace.WriteLine(result);
}).ToArray();
// Await …Run Code Online (Sandbox Code Playgroud)