首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在循环中使用await

如何在循环中使用await
EN

Stack Overflow用户
提问于 2013-10-17 23:53:20
回答 3查看 98.2K关注 0票数 100

我正在尝试创建一个在集合上做一些工作的异步控制台应用程序。我有一个使用并行for循环的版本,另一个使用async/await的版本。我期望async/await版本的工作方式与并行版本相似,但它是同步执行的。我做错了什么?

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        var worker = new Worker();
        worker.ParallelInit();
        var t = worker.Init();
        t.Wait();
        Console.ReadKey();
    }
}

public class Worker
{
    public async Task<bool> Init()
    {
        var series = Enumerable.Range(1, 5).ToList();
        foreach (var i in series)
        {
            Console.WriteLine("Starting Process {0}", i);
            var result = await DoWorkAsync(i);
            if (result)
            {
                Console.WriteLine("Ending Process {0}", i);
            }
        }

        return true;
    }

    public async Task<bool> DoWorkAsync(int i)
    {
        Console.WriteLine("working..{0}", i);
        await Task.Delay(1000);
        return true;
    }

    public bool ParallelInit()
    {
        var series = Enumerable.Range(1, 5).ToList();
        Parallel.ForEach(series, i =>
        {
            Console.WriteLine("Starting Process {0}", i);
            DoWorkAsync(i);
            Console.WriteLine("Ending Process {0}", i);
        });
        return true;
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-10-18 00:06:04

使用await关键字的方式告诉C#,您希望在每次通过循环时都等待,这不是并行的。你可以像这样重写你的方法来做你想做的事情,方法是存储一个Task的列表,然后用Task.WhenAll对它们进行await

代码语言:javascript
复制
public async Task<bool> Init()
{
    var series = Enumerable.Range(1, 5).ToList();
    var tasks = new List<Task<Tuple<int, bool>>>();
    foreach (var i in series)
    {
        Console.WriteLine("Starting Process {0}", i);
        tasks.Add(DoWorkAsync(i));
    }
    foreach (var task in await Task.WhenAll(tasks))
    {
        if (task.Item2)
        {
            Console.WriteLine("Ending Process {0}", task.Item1);
        }
    }
    return true;
}

public async Task<Tuple<int, bool>> DoWorkAsync(int i)
{
    Console.WriteLine("working..{0}", i);
    await Task.Delay(1000);
    return Tuple.Create(i, true);
}
票数 138
EN

Stack Overflow用户

发布于 2013-10-17 23:56:13

您的代码将等待每个操作(使用await)完成,然后再开始下一次迭代。

因此,你得不到任何并行性。

如果您希望并行运行现有的异步操作,则不需要await;您只需获取Task的集合,并调用Task.WhenAll()返回一个等待所有这些操作的任务:

代码语言:javascript
复制
return Task.WhenAll(list.Select(DoWorkAsync));
票数 41
EN

Stack Overflow用户

发布于 2013-10-18 00:05:47

代码语言:javascript
复制
public async Task<bool> Init()
{
    var series = Enumerable.Range(1, 5);
    Task.WhenAll(series.Select(i => DoWorkAsync(i)));
    return true;
}
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19431494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档