【发布时间】:2018-05-16 20:05:09
【问题描述】:
我正在通过 HTTP 实现简单的数据加载器,遵循我之前的问题 C# .NET Parallel I/O operation (with throttling) 中的提示,Throttling asynchronous tasks 回答了。
我将加载和反序列化分开,假设一个可能比另一个慢/快。我也想限制下载,但不想限制反序列化。因此我使用了两个块和一个缓冲区。
不幸的是,我面临的问题是,此管道有时处理的消息少于消耗的消息(我从目标服务器知道,我确实执行了 n 请求,但最终得到的响应更少)。
我的方法是这样的(没有错误处理):
public async Task<IEnumerable<DummyData>> LoadAsync(IEnumerable<Uri> uris)
{
IList<DummyData> result;
using (var client = new HttpClient())
{
var buffer = new BufferBlock<DummyData>();
var downloader = new TransformBlock<Uri, string>(
async u => await client.GetStringAsync(u),
new ExecutionDataflowBlockOptions
{ MaxDegreeOfParallelism = _maxParallelism });
var deserializer =
new TransformBlock<string, DummyData>(
s => JsonConvert.DeserializeObject<DummyData>(s),
new ExecutionDataflowBlockOptions
{ MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded });
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
downloader.LinkTo(deserializer, linkOptions);
deserializer.LinkTo(buffer, linkOptions);
foreach (Uri uri in uris)
{
await downloader.SendAsync(uri);
}
downloader.Complete();
await downloader.Completion;
buffer.TryReceiveAll(out result);
}
return result;
}
所以更具体地说,我有 100 个要加载的 URL,但我得到了 90-99 个响应。没有错误,服务器处理了 100 个请求。这是随机发生的,大部分时间代码行为正确。
【问题讨论】:
-
您唯一等待完成的
downloader在完成消息时仍然必须反序列化并放入缓冲区。 -
@JSteward 哦,...我无语了,谢谢! (我严重误解了
PropagateCompletion属性)
标签: c# tpl-dataflow