仍在等待时的 RanToCompletion
RanToCompletion when still awaiting
我需要编写一个异步加载和解析多个网站的方法。
这是我的方法的简化代码。
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
class 使用 HttpClient
加载站点并在处置时处置它。完整代码还使用 CancellationToken
取消并使用 SemaphoreSlim
降低并行度。
问题是当任务开始等待已解析的数据时,它的状态设置为 RanToCompletion
。然后程序传递 Task.WhenAll
并处理 HTMLParser
导致 HttpClient
中的 OperationCanceledException
s。
正如我在评论中所说,您不应该明确创建 Task
。我认为您需要的是:
using (HTMLParser parser = new HTMLParser(proxy))
{
var tasks = totalSites.Select( s => populateEntity(s)).ToArray();
/* returned tasks are already hot */
//foreach (var task in tasks)
// task.Start();
await Task.WhenAll(tasks).ConfigureAwait(false);
}
然后分别:
public async Task<WhateverSIs> populateEntity(WhateverSIs s)
{
s.Entity = await parser.GetSiteDataAsync(s.Entity).ConfigureAwait(false);
return s;
}
我们不会显式创建任何 Tasks
- 我们只是使用 async
方法公开的那些,包括 GetSiteDataAsync
.
我需要编写一个异步加载和解析多个网站的方法。 这是我的方法的简化代码。
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
class 使用 HttpClient
加载站点并在处置时处置它。完整代码还使用 CancellationToken
取消并使用 SemaphoreSlim
降低并行度。
问题是当任务开始等待已解析的数据时,它的状态设置为 RanToCompletion
。然后程序传递 Task.WhenAll
并处理 HTMLParser
导致 HttpClient
中的 OperationCanceledException
s。
正如我在评论中所说,您不应该明确创建 Task
。我认为您需要的是:
using (HTMLParser parser = new HTMLParser(proxy))
{
var tasks = totalSites.Select( s => populateEntity(s)).ToArray();
/* returned tasks are already hot */
//foreach (var task in tasks)
// task.Start();
await Task.WhenAll(tasks).ConfigureAwait(false);
}
然后分别:
public async Task<WhateverSIs> populateEntity(WhateverSIs s)
{
s.Entity = await parser.GetSiteDataAsync(s.Entity).ConfigureAwait(false);
return s;
}
我们不会显式创建任何 Tasks
- 我们只是使用 async
方法公开的那些,包括 GetSiteDataAsync
.