c# - 如何在 Parallel.ForEach 中应用异步
问题描述
在Parallel.ForEach
方法内部,当我使用异步方法DownloadWebsiteAsync
获取外部资源时,调用方法executeAsync_Click
不会等待方法并在完成工作RunDownloadParallelAsync
之前打印结果。RunDownloadParallelAsync
当我更改DownloadWebsiteAsync
为DownloadWebsiteSync
(以同步方式工作)时,一切正常。
private async void executeAsync_Click(object sender, RoutedEventArgs e)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
var results = await DemoMethods.RunDownloadParallelAsync();
PrintResults(results);
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
resultsWindow.Text += $"Total execution time: { elapsedMs }";
}
public static async Task<List<WebsiteDataModel>> RunDownloadParallelAsync()
{
List<string> websites = PrepData();
List<WebsiteDataModel> output = new List<WebsiteDataModel>();
await Task.Run(() =>
Parallel.ForEach<string>(websites, async (site) =>
{
WebsiteDataModel results =await DownloadWebsiteAsync(site);
output.Add(results);
})
);
return output;
}
解决方案
Parallel
并且async
通常不能很好地协同工作。
在这里,您希望允许多个 HTTP 请求同时发生,但在工作中抛出多个线程将无济于事。
相反,只需使用async
:
public static async Task<IEnumerable<WebsiteDataModel>> RunDownloadParallelAsync()
{
return await Task.WhenAll(PrepData().Select(DownloadWebsiteAsync));
}
每个请求都将被发送而无需等待先前的响应。
推荐阅读
- ruby - 使用 rails 获取桌面中文件的路径
- javascript - 如何在 blob/buffer 的 MIME 类型之间进行转换?
- c# - 难以理解沿局部和全球空间统一的运动
- c++ - 有没有什么东西限制了未来的 C++ 标准引入多个返回值?
- openssl - 使用 OpenSSL CLI 从 x509 证书获取链或 CA 颁发者
- bash - 使用包含单引号的 grep 命令创建别名
- php - Php 不会捕获内容的结果,而只会捕获标题
- python - Python 在 MacOS 10.15 Beta (19A582a) 上使用“/usr/lib/libcrypto.dylib”崩溃
- android - 如何在 Xamarin.Forms Android 微调器中更改日期顺序(从默认到日/月/年)?
- python - 如何将整数转换为时间