通常の反復ブロック (つまり、「yield return」) は、「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;
}
ただし、「リソースからメッセージ文字列をロードできません」というコンパイラ エラーが発生します。
もう一つの試みは次のとおりです。
async Task<IEnumerable<Foo>> Method(String [] Strs)
{
foreach(var str in strs)
{
yield return await DoSomethingAsync( str)
}
}
しかし、再びコンパイラは「リソースからメッセージ文字列をロードできません」というエラーを返します。
これが私のプロジェクトの実際のプログラミングコードです
これは、リスト タスクがある場合に非常に便利です。このタスクは URL から HTML をダウンロードでき、構文「yield 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;
}
しかし、そうしなければならないようです。
ご協力いただきありがとうございます。
ベストアンサー1
あなたが説明していることは、メソッドで実現できますTask.WhenAll
。コードが単純なワンライナーになる方法に注目してください。各 URL がダウンロードを開始し、WhenAll
それらの操作を 1 つにまとめてTask
待機できる状態にします。
Task<IEnumerable<string>> DownLoadAllUrls(string[] urls)
{
return Task.WhenAll(from url in urls select DownloadHtmlAsync(url));
}