【发布时间】:2017-09-01 08:22:51
【问题描述】:
我需要编写一个异步加载和解析多个网站的方法。 这是我的方法的简化代码。
using (HTMLParser parser = new HTMLParser(proxy))
{
var tasks = totalSites.Select( s =>
{
return new Task( async () =>
{
s.Entity = await parser.GetSiteDataAsync(s.Entity).ConfigureAwait(false);
});
}).ToArray();
foreach (var task in tasks)
task.Start();
await Task.WhenAll(tasks).ConfigureAwait(false);
}
HTMLParser 类使用HttpClient 加载站点并在处置时处置它。完整代码还使用CancellationToken 取消并使用SemaphoreSlim 降低并行度。
问题是当任务开始等待解析数据时,它的状态设置为RanToCompletion。然后程序通过Task.WhenAll 并处理HTMLParser 导致OperationCanceledExceptions 在HttpClient。
【问题讨论】:
-
如果您的代码将受 I/O 限制,那么您的方法通常不应显式创建新的
Task对象。我认为您当前的代码以Tasks 包装其他Tasks 结尾,这并不大。 -
@GWigWam ,对不起,我错过了简化我的代码。
s用于创建vm。 @Damien_The_Unbeliever 我认为你是对的:我需要创建多个任务来并行加载多个网站。 -
@AndreyAlonzov - 但对于 I/O 绑定工作,您不应该创建
Tasks - 您应该利用async和await但只有Tasks 你应该处理的是那些由async方法返回的。 -
@Damien_The_Unbeliever 如果我将使用该任务,我如何一次加载 40 个网站。
标签: c# asynchronous async-await task-parallel-library dotnet-httpclient