Is it possible to “await yield return DoSomethingAsync()”

前端 未结 9 963
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-27 14:08

Are regular iterator blocks (i.e. \"yield return\") incompatible with \"async\" and \"await\"?

This gives a good idea of what I\'m trying to do:

asyn         


        
9条回答
  •  时光说笑
    2020-11-27 14:32

    According to the new features at C# 8.0 (link#1 and link#2) we'll have IAsyncEnumerable interface support that will allow to implement your second attempt. It will look like this:

    async Task DoSomethingAsync(string url)
    {
        ...
    }       
    // producing IAsyncEnumerable
    async IAsyncEnumerable DownLoadAllURL(string[] strs)
    {
        foreach (string url in strs)
        {
            yield return await DoSomethingAsync(url);
        }
    }
    ...
    // using
    await foreach (Foo foo in DownLoadAllURL(new string[] { "url1", "url2" }))
    {
        Use(foo);
    }
    

    We can achieve the same behavior at C# 5 but with a different semantics:

    async Task DoSomethingAsync(string url)
    {
        ...
    }
    IEnumerable> DownLoadAllURL(string[] strs)
    {
        foreach (string url in strs)
        {
            yield return DoSomethingAsync(url);
        }
    }
    
    // using
    foreach (Task task in DownLoadAllURL(new string[] { "url1", "url2" }))
    {
        Foo foo = await task;
        Use(foo);
    }
    

    Brian Gideon's answer implies that the calling code will get asynchronously a collection of results that were obtained in parallel. The code above implies that the calling code will get results like from a stream one by one in asynchronous manner.

提交回复
热议问题