宽松有序的并发性循环? [英] Loosely-ordered concurrency with loops?

查看:100
本文介绍了宽松有序的并发性循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code,是为了获取从REST服务(获取(我)电话),然后填充一个矩阵数据(未显示;这种情况在 addLabels())与它们之间的关系。

I have the following code that is meant to fetch data from a REST service (the Get(i) calls), then populate a matrix (not shown; this happens within addLabels()) with their relationships.

所有获取()的呼叫可在彼此平行运行,但是它们必须任何进入第二环路(前所有完成,其中,再一次,该呼叫可在彼此平行运行)。在 addLabel()通话依靠从工作的的get()要求是完整的。

All of the Get() calls can run in parallel to each other, but they must all be finished before anything enters the second loop (where, once again, the calls can run in parallel to each other). The addLabel() calls depend on the work from the Get() calls to be complete.

**要跨人这个职位磕磕绊绊,这code是解决方案:**

** To anyone stumbling across this post, this code is the solution:**

private async void GetTypeButton_Click(object sender, RoutedEventArgs e)
{
    await PokeType.InitTypes(); // initializes relationships in the matrix

    var table = PokeType.EffectivenessMatrix;

    // pretty-printing the table
    // ...
    // ...
}

private static bool initialized = false;

public static async Task InitTypes()
{
    if (initialized) return;

    // await blocks until first batch is finished
    await Task.WhenAll(Enumerable.Range(1, NUM_TYPES /* inclusive */).Select(i => Get(i)));

    // doesn't need to be parallelized because it's quick work.
    foreach(PokeType type in cachedTypes.Values)
    {
        JObject data = type.GetJsonFromCache();
        addLabels(type, (JArray)data["super_effective"], Effectiveness.SuperEffectiveAgainst);
        addLabels(type, (JArray)data["ineffective"], Effectiveness.NotVeryEffectiveAgainst);
        addLabels(type, (JArray)data["no_effect"], Effectiveness.UselessAgainst);
    }

    initialized = true;
}

public static async Task<PokeType> Get(int id);

由于code目前正在写的, InitTypes()方法试图进入两者同时进行循环;在 cachedTypes 词典是空的,因为第一次循环未完成填充它,所以它永远不会运行,没有关系的构建。

As the code is currently written, the InitTypes() method attempts to enter both loops simultaneously; the cachedTypes dictionary is empty because the first loop hasn't finished populating it yet, so it never runs and no relationships are constructed.

我怎样才能正确地构建这个功能呢?谢谢!

How can I properly structure this function? Thanks!

推荐答案

并行和异步等待不要一起去好。您的异步拉姆达前pression实际上是异步无效,因为的Parallel.For excpects一个动作&LT; INT方式&gt; ,这意味着的Parallel.For 不能等待操作完成

Parallel and async-await don't go together well. Your async lambda expression is actually async void since Parallel.For excpects an Action<int>, which means that Parallel.For can't wait for that operation to complete.

如果你想同时调用获取(我)多次,恨不得在继续之前完成需要使用任务.WhenAll

If you're trying to call Get(i) multiple times concurrently and wait for them to complete before moving on you need to use Task.WhenAll:

await Task.WhenAll(Enumerable.Range(1, NUM_TYPES).Select(() => Get(i)))

这篇关于宽松有序的并发性循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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