我需要使用代理来下载论坛。我的代码的问题是它只占用了我互联网带宽的 10%。我还读到我需要使用单个 HttpClient
实例,但是对于多个代理我不知道该怎么做。更改 MaxDegreeOfParallelism
不会改变任何内容。
public static IAsyncEnumerable<IFetchResult> FetchInParallelAsync(
this IEnumerable<Url> urls, FetchContext context)
{
var fetchBlcock = new TransformBlock<Url, IFetchResult>(
transform: url => url.FetchAsync(context),
dataflowBlockOptions: new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 128
}
);
foreach(var url in urls)
fetchBlcock.Post(url);
fetchBlcock.Complete();
var result = fetchBlcock.ToAsyncEnumerable();
return result;
}
每次调用 FetchAsync
都会创建或重用带有 WebProxy
的 HttpClient
。
public static async Task<IFetchResult> FetchAsync(this Url url, FetchContext context)
{
var httpClient = context.ProxyPool.Rent();
var result = await url.FetchAsync(httpClient, context.Observer, context.Delay,
context.isReloadWithCookie);
context.ProxyPool.Return(httpClient);
return result;
}
public HttpClient Rent()
{
lock(_lockObject)
{
if (_uninitiliazedDatacenterProxiesAddresses.Count != 0)
{
var proxyAddress = _uninitiliazedDatacenterProxiesAddresses.Pop();
return proxyAddress.GetWebProxy(DataCenterProxiesCredentials).GetHttpClient();
}
return _proxiesQueue.Dequeue();
}
}
我是软件开发的新手,但使用成百上千个代理异步下载的任务看起来是一项微不足道的任务,许多人应该已经面对并找到了正确的方法来完成它。到目前为止,我无法在互联网上找到任何解决我的问题的方法。对如何实现最大下载速度有任何想法吗?
最佳答案
让我们来看看这里发生了什么:
var result = await url.FetchAsync(httpClient, context.Observer, context.Delay, context.isReloadWithCookie);
在继续下一项之前,您实际上是在await
ing。这就是为什么它是异步而不是并行编程的原因。 async in Microsoft docs
The await keyword is where the magic happens. It yields control to the caller of the method that performed await, and it ultimately allows a UI to be responsive or a service to be elastic.
本质上,它释放了调用线程去做其他事情但是原始调用代码暂停执行,直到 IO 操作完成。
现在解决你的问题:
- 您可以在这里使用这个出色的解决方案:foreach async
- 您可以使用并行库在不同的线程中执行您的代码。
类似于 Parallel for example 中的以下内容
Parallel.For(0, urls.Count,
index => fetchBlcock.Post(urls[index])
});
关于c# - 多个带有代理的 HttpClients,试图达到最大下载速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64619489/