我的项目是一个html解析器,并行加载带有许多HttpClients的html页面(我的列表中每个代理一个客户端),然后使用HtmlAgilityPack(用于html解析的第三方库)解析加载的html页面。
此方法使用HttpClient加载页面。所以它使用网络,CPU使用率低:
LoadObjectPageAsync(client, i)
此方法解析加载的页面。不使用网络,使用多CPU:
ParseObjectPageAsync(i)
在我的项目中,我同时为我的WebProxy列表中的每个代理执行了一些异步方法:
Private Async Function LoadAndParseAsync(ByVal _proxy As WebProxy) As Task
Dim client As HttpClient = CreateProxyHttpClient(_proxy, 10000)
For i = 0 To URLS.Length - 1
Await LoadObjectPageAsync(client, i)
ParseObjectPageAsync(i)
Next
End Function
每个HttpClient逐页加载,每次加载完成后,我开始解析该页面的任务而忘记它。
我的互联网频道带宽为30 Mbps。这是在此方法执行期间的下载速度(我无法发布低评级的图像):
http://oi60.tinypic.com/2ebae4n.jpg
CPU使用~50-60%。但在这种情况下,互联网频道并不总是在执行期间完全加载。
如果我执行上面没有这个字符串的方法:
ParseObjectPageAsync(i)
(所以我只是不解析加载的页面),然后我有了这个:
http://oi60.tinypic.com/rmu5gn.jpg
CPU使用率约为5-10%。但带宽满载。这就是我想要解析的内容。
所以,当我调用ParseObjectPageAsync(i)方法时,我希望它对网络使用没有影响。但它以某种方式影响,尽管CPU在执行期间没有满载,但只有50-60%。因此解析任务会中断加载任务。这就是我想要解决的问题,因为主要的优先事项是最大限度地利用互联网渠道。
也许有办法将Parse任务的优先级设置为低。或者其他解决问题的方法。
我可以阅读VB和C#代码。对不起我的英语不好。
上传: ParseObjectPageAsync 方法是:
Private Async Sub ParseObjectPageAsync(ByVal _num As Integer)
// Await is a first keyword, so the whole method
// must run asynchronously, as I expect.
Await Task.Run(Sub()
// and here some proccessing with loaded page.
End Sub)
End Sub
答案 0 :(得分:1)
对于混合异步和CPU绑定的工作,我建议TPL Dataflow。您可以设置一个基本管道,其中第一个TransformBlock
获取URL并(异步)下载它们,第二个TransformBlock
执行解析。然后,您可以根据需要调整两个块的MaxDegreeOfParallelism
选项。