异步任务是两次评估 [英] Async tasks are evaluated twice

查看:105
本文介绍了异步任务是两次评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用下面的方法来异步做一些任务,并在同一时间:

I use the following method to do some tasks asynchronously and at the same time:

public async Task<Dictionary<string, object>> Read(string[] queries)
{
    var results = queries.Select(query => new Tuple<string, Task<object>>(query, LoadDataAsync(query)));

    await Task.WhenAll(results.Select(x => x.Item2).ToArray());

    return results
        .ToDictionary(x => x.Item1, x => x.Item2.Result);
}

我要的方法来调用 LoadDataAsync 在同一时间阵列中的每个字符串,然后等待,直到所有任务完成并返回结果。

I want the method to call LoadDataAsync for each string in the array at the same time, then wait until all tasks are finished and return the result.


  • 如果我像这样运行的方法,它调用 LoadDataAsync 两次,每次项目,一旦在的await ... 线,一旦在最后。结果属性的getter。

  • 如果我删除的await ... 行,Visual Studio的警告我整个的方法将并行运行,因为没有等待该方法的内通话。

  • If I run the method like this, it invokes LoadDataAsync twice for each item, once at the await ... line, and once at the final .Result property getter.
  • If I remove the await ... line, Visual Studio warns me that the whole method would run in parallel, since there are not await calls inside of the method.

我在做什么错了?

有没有更好的(短)的方式做?

推荐答案

再次

如果我可以教人们了解LINQ一件事这将是一个查询的价值在于执行查询,执行查询的不是结果的对象

您创建查询一次,产生一个对象,它可以执行查询。然后,执行查询两次。你不幸创建查询,不仅计算出一个值,但会产生副作用,因此,在执行查询两次产生两倍的副作用。 不要产生副作用,可重用的查询对象,永远。查询是的的机制提出问题的,因此他们的名字。他们不打算成为一个控制流机制,但这是你用他们的东西。

You create the query once, producing an object which can execute the query. You then execute the query twice. You have unfortunately created a query that not only computes a value but produces a side effect, and therefore, executing the query twice produces the side effect twice. Do not make reusable query objects that produce side effects, ever. Queries are a mechanism for asking questions, hence their name. They are not intended to be a control flow mechanism, but that's what you're using them for.

执行查询产生的两倍自然是因为两种不同的结果的查询的结果可能有两种执行之间变化的。如果查询查询数据库,也就是说,该数据库可能执行之间变化。如果您的查询是什么都在伦敦的每一个客户的姓氏?答案可能的变更的从毫秒到毫秒,但是的问题的保持不变。一定要记住,查询重新presents的问题

Executing the query twice produces two different results because of course the results of the query could have changed between the two executions. If the query is querying a database, say, the database could have changed between executions. If your query is "what are all the last names of every customer in London?" the answer could change from millisecond to millisecond, but the question stays the same. Always remember, the query represents a question.

我会倾向于不写东西的查询。用的foreach循环创建副作用。

I would be inclined to write something without queries. Use "foreach" loops to create side effects.

public async Task<Dictionary<string, object>> Read(IEnumerable<string> queries)
{
    var tasks = new Dictionary<string, Task<object>>();
    foreach (string query in queries)
        tasks.Add(query, LoadDataAsync(query));
    await Task.WhenAll(tasks.Values);
    return tasks.ToDictionary(x => x.Key, x => x.Value.Result);
}

这篇关于异步任务是两次评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆