常规的迭代器块(即"yield“)是否与"async”和"await“不兼容?
这给了我一个很好的想法,我想要做什么:
async Task<IEnumerable<Foo>> Method(String [] Strs)
{
// I want to compose the single result to the final result, so I use the SelectMany
var finalResult = UrlStrings.SelectMany(link => //i have an Urlstring Collection
await UrlString.DownLoadHtmlAsync() //download single result; DownLoadHtmlAsync method will Download the url's html code
);
return finalResult;
}
然而,我得到一个编译器错误,引用"unable to load message string from resources“。
下面是另一个尝试:
async Task<IEnumerable<Foo>> Method(String [] Strs)
{
foreach(var str in strs)
{
yield return await DoSomethingAsync( str)
}
}
但是,编译器再次返回一个错误:"unable to load message string from resources“。
以下是我的项目中的实际编程代码
当我有一个列表任务时,这是非常有用的,这个任务可以从一个网址下载超文本标记语言,我使用了语法“very return await task",结果是我想要IEnumerable<Foo>
。我不想写这样的代码:
async Task<IEnumerable<String>> DownLoadAllURL(String [] Strs)
{
List<Foo> htmls= new ...
foreach(var str in strs)
{
var html= await DownLoadHtmlAsync( str)
htmls.Add(item)
}
return htmls;
}
但看起来我不得不这么做。
谢谢你的帮助。
发布于 2011-07-09 02:06:13
您所描述的内容可以使用Task.WhenAll
方法来完成。注意代码是如何变成一个简单的一行程序的。发生的事情是,每个单独的Task
开始下载,然后使用WhenAll
将这些操作组合到一个可以等待的Task
中。
Task<IEnumerable<string>> DownLoadAllUrls(string[] urls)
{
return Task.WhenAll(from url in urls select DownloadHtmlAsync(url));
}
发布于 2016-02-26 04:01:03
我知道我的答案来得太晚了,但这里有另一个简单的解决方案,可以使用这个库来实现:
GitHub:https://github.com/tyrotoxin/AsyncEnumerable
NuGet.org:https://www.nuget.org/packages/AsyncEnumerator/
它比Rx简单得多。
using System.Collections.Async;
static IAsyncEnumerable<string> ProduceItems(string[] urls)
{
return new AsyncEnumerable<string>(async yield => {
foreach (var url in urls) {
var html = await UrlString.DownLoadHtmlAsync(url);
await yield.ReturnAsync(html);
}
});
}
static async Task ConsumeItemsAsync(string[] urls)
{
await ProduceItems(urls).ForEachAsync(async html => {
await Console.Out.WriteLineAsync(html);
});
}
发布于 2017-10-05 12:07:38
https://stackoverflow.com/questions/5061761
复制相似问题