异步运行同一方法的多个实例?

xam*_*mir 3 c# performance asynchronous task async-await

我的要求很奇怪.

我有SomeMethod()哪些电话GetDataFor().

public void SomeMethod()
{
    for(int i = 0; i<100; i++) {
        var data = GetDataFor(i);
    }
}

public data GetDataFor(int i) {
    //call a remote API
    //to generate data for i
    //store to database
    return data;
}
Run Code Online (Sandbox Code Playgroud)

对于每一个i,最终结果总是不同的.有没有需要等待GetDataFor(i)调用之前完成GetDataFor(i+1).

换句话说,我需要:

  • 呼吁GetDataFor()每个i+1 立即成功后调用i(并行调用它们看起来不可能的)
  • 等到所有 100个实例GetDataFor()都完成运行
  • 离开范围 SomeMethod()

按照YK1的回答,我试图像这样修改它:

public async Task<void> SomeMethod()
{
    for(int i = 0; i < 100; i++) {
        var task = Task.Run(() => GetDataFor(i));
        var data = await task;
    }
}
Run Code Online (Sandbox Code Playgroud)

它没有抛出任何错误,但我需要理解这背后的概念:

  • 如何task区分不同的呼叫await?它越来越多了.
  • 这样做是否明显错误?那么,怎么做呢?

Art*_*aca 9

你可以使用Parallel.For:

public void SomeMethod()
{
    Parallel.For(0, 100, i =>
    {
        var data = GetDataFor(i);
        //Do something
    });
}

public data GetDataFor(int i)
{
    //generate data for i
    return data;
}
Run Code Online (Sandbox Code Playgroud)

编辑:

并行循环的语法forforeach您已知的和循环非常相似,但并行循环在具有可用核心的计算机上运行得更快.另一个区别是,与顺序循环不同,没有为并行循环定义执行顺序.步骤通常同时并行进行.有时,两个步骤的顺序与循环顺序时相反.唯一的保证是所有循环的迭代都将在循环结束时运行.

对于并行循环,并行程度不需要由代码指定.相反,运行时环境在尽可能多的内核上同时执行循环的步骤.无论有多少核心,循环都能正常工作.如果只有一个核心,则性能接近(相当于几个百分点)顺序等效.如果有多个核心,性能会提高; 在许多情况下,性能与核心数量成比例地提高.

您可以在此处查看更详细的说明.

  • 这只会根据您拥有的核心数并行运行.如果你有1个核心,那么什么都不会改善. (2认同)