我有一个.Net搜寻器,它在用户发出请求时正在运行(因此,它必须快速)。它可以实时抓取400多个链接。 (这是业务要求。)
问题:我需要检测链接是xml(以RSS或原子供稿为例)还是html。如果链接是xml,那么我将继续处理,但是如果链接是html,则可以跳过它。通常,我有2个xml和398+个html。目前,我有多个线程在运行,但处理速度仍然很慢,通常需要75秒才能运行10个线程来处理400多个链接,或者需要280秒才能运行1个线程。 (我想添加更多线程,但请参见下文。)
我面临的挑战是我按如下方式阅读信息流:
var request = WebRequest.Create(requestUriString: uri.AbsoluteUri);
// ....
var response = await request.GetResponseAsync();
//....
using (var reader = new StreamReader(stream: response.GetResponseStream(), encoding: encoding)) {
char[] buffer = new char[1024];
await reader.ReadAsync(buffer: buffer, index: 0, count: 1024);
responseText = new string(value: buffer);
}
// parse first byts of reasponseText to check if xml
问题在于,我只获得1024的优化是完全没有用的,因为GetResponseAsync仍在下载整个流,如我所见。 (我的另一个选择是查找标题ContentType,但这与AFAIK十分相似,因为无论如何我都会得到内容-以防万一您不建议使用OPTIONS,但到目前为止我还没有使用过OPTIONS-另外xml的内容类型标记可能不正确(?),我会错过一些内容。)
如果我缺少任何优化,请帮忙,因为我用尽了所有想法。
(我确实考虑过通过分散多台服务器上的负载来优化此设计,以便使网络与并行性保持平衡,但这与当前体系结构相比有一些变化,这是我目前无法承受的。时间。)
答案 0 :(得分:0)
如果您可以依靠Content-Type,则使用HEAD请求可以大大加快请求的速度。
例如
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage() { Method = HttpMethod.Head});
仅显示基本用法。显然,您需要在请求中添加uri和其他任何必需的内容。
还要注意,即使有10个线程,400个请求也可能会花费相当长的时间。 400/10表示40个顺序请求。除非对关闭的服务器发出请求,否则200ms是一个很好的响应时间,意味着最少8秒。可能会很慢的Ovserseas服务很容易将其推迟到30-40秒不可避免的延迟,除非您增加线程数量以并行处理更多请求。
Dataflow (Task Parallel Library)对于编写具有方便的MaxDegreeOfParallelism属性的并行管道非常有用,该属性可轻松调整可以运行的并行实例的数量。