如何使用AWAIT在一个循环 [英] How to use await in a loop

查看:175
本文介绍了如何使用AWAIT在一个循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个异步的控制台应用程序,并在集合的一些工作。我有循环使用并行使用异步另一个版本一个版本/等待。我预计异步/等待版本的工作方式与水货版本,但它同步执行。我在做什么错了?

 类节目
{
    静态无效的主要(字串[] args)
    {
        VAR工人=新员工();
        worker.ParallelInit();
        VAR T = worker.Init();
        t.Wait();
        Console.ReadKey();
    }
}公共类工人
{
    公共异步任务<布尔>在里面()
    {
        无功串联= Enumerable.Range(1,5).ToList();
        的foreach(串联变种I)
        {
            Console.WriteLine(启动过程{0},我);
            VAR的结果=等待DoWorkAsync(I)
            如果(结果)
            {
                Console.WriteLine(结束进程{0},我);
            }
        }        返回true;
    }    公共异步任务<布尔> DoWorkAsync(int i)以
    {
        Console.WriteLine(工作.. {0},我);
        等待Task.Delay(1000);
        返回true;
    }    公共BOOL ParallelInit()
    {
        无功串联= Enumerable.Range(1,5).ToList();
        Parallel.ForEach(系列,I =>
        {
            Console.WriteLine(启动过程{0},我);
            DoWorkAsync(ⅰ);
            Console.WriteLine(结束进程{0},我);
        });
        返回true;
    }
}


解决方案

您正在使用的方式的await 关键字告诉你希望每次打发时间等待C#通过循环,这是不平行的。你可以重写你的方法这样做你想要的东西,通过存储工作和然后等待 ING名单他们都用 Task.WhenAll

 公共异步任务<布尔>在里面()
{
    无功串联= Enumerable.Range(1,5).ToList();
    VAR任务=新的List<任务&LT元组LT; INT,BOOL>>>();
    的foreach(串联变种I)
    {
        Console.WriteLine(启动过程{0},我);
        tasks.Add(DoWorkAsync(I));
    }
    的foreach(在等待Task.WhenAll(VAR任务任务))
    {
        如果(task.Item2)
        {
            Console.WriteLine(结束进程{0},task.Item1);
        }
    }
    返回true;
}公共异步任务&LT元组LT; INT,BOOL>> DoWorkAsync(int i)以
{
    Console.WriteLine(工作.. {0},我);
    等待Task.Delay(1000);
    返回Tuple.Create(我,真);
}

I'm trying to create an asynchronous console app that does a some work on a collection. I have one version which uses parallel for loop another version that uses async/await. I expected the async/await version to work similar to parallel version but it executes synchronously. What am I doing wrong?

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;
    }
}

解决方案

The way you're using the await keyword tells C# that you want to wait each time you pass through the loop, which isn't parallel. You can rewrite your method like this to do what you want, by storing a list of Tasks and then awaiting them all with Task.WhenAll.

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);
}

这篇关于如何使用AWAIT在一个循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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