我已經改變了問題的標題來反映這個問題我有,但是還就如何輕鬆地實現這個答案。
我試圖讓第二個方法返回Task<TResult>
而不是Task
作爲第一個方法,但我得到錯誤的級聯爲試圖解決它的後果。
- 我
await body(partition.Current);
- 前加入
return
反過來要求我先下添加,所以我下面 - 添加
return null
return語句但是現在的select語句抱怨說,它不能從查詢 推斷類型參數
- 我將
Task.Run
更改爲Task.Run<TResult>
,但沒有成功。
我怎樣才能解決這個問題?
第一種方法來自http://blogs.msdn.com/b/pfxteam/archive/2012/03/05/10278165.aspx,第二種方法是,我試圖創造過載。
public static class Extensions
{
public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(dop)
select Task.Run(async delegate
{
using (partition)
while (partition.MoveNext())
await body(partition.Current);
}));
}
public static Task ForEachAsync<T, TResult>(this IEnumerable<T> source, int dop, Func<T, Task<TResult>> body)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(dop)
select Task.Run(async delegate
{
using (partition)
while (partition.MoveNext())
await body(partition.Current);
}));
}
}
用例:
使用這種方法,我想下載並行且異步多個文件:
private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Artist artist = await GetArtist();
IEnumerable<string> enumerable = artist.Reviews.Select(s => s.ImageUrl);
string[] downloadFile = await DownloadFiles(enumerable);
}
public static async Task<string[]> DownloadFiles(IEnumerable<string> enumerable)
{
if (enumerable == null) throw new ArgumentNullException("enumerable");
await enumerable.ForEachAsync(5, s => DownloadFile(s));
// Incomplete, the above statement is void and can't be returned
}
public static async Task<string> DownloadFile(string address)
{
/* Download a file from specified address,
* return destination file name on success or null on failure */
if (address == null)
{
return null;
}
Uri result;
if (!Uri.TryCreate(address, UriKind.Absolute, out result))
{
Debug.WriteLine(string.Format("Couldn't create URI from specified address: {0}", address));
return null;
}
try
{
using (var client = new WebClient())
{
string fileName = Path.GetTempFileName();
await client.DownloadFileTaskAsync(address, fileName);
Debug.WriteLine(string.Format("Downloaded file saved to: {0} ({1})", fileName, address));
return fileName;
}
}
catch (WebException webException)
{
Debug.WriteLine(string.Format("Couldn't download file from specified address: {0}", webException.Message));
return null;
}
}
這並不完全清楚你期望的結果是什麼。你傳遞了一系列'T'值,並在它們兩個上執行相同的函數 - 你會期望從「Task'返回什麼樣的結果? –
我想在這種情況下得到一個任務,我已經在我的問題上添加了一個例子。 –
Aybe
*「使用這種方法,我想以並行和異步的方式下載多個文件」*:''Parallel.Foreach'還不夠? –