c# - 多个带有代理的 HttpClients,试图达到最大下载速度

标签 c# asynchronous web-scraping httpclient tpl-dataflow

我需要使用代理来下载论坛。我的代码的问题是它只占用了我互联网带宽的 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 都会创建或重用带有 WebProxyHttpClient

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);

在继续下一项之前,您实际上是在awaiting。这就是为什么它是异步而不是并行编程的原因。 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 操作完成。

现在解决你的问题:

  1. 您可以在这里使用这个出色的解决方案:foreach async
  2. 您可以使用并行库在不同的线程中执行您的代码。

类似于 Parallel for example 中的以下内容

Parallel.For(0, urls.Count,
         index => fetchBlcock.Post(urls[index])
});

关于c# - 多个带有代理的 HttpClients,试图达到最大下载速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64619489/

相关文章:

c# - 需要一些精简库/代码来创建缩略图并且最适合与 ASP.NET MVC 一起使用

python - 尝试/除了抓取 URL 末尾带有 3 个随机数字的网站

python - 使用 WebDriver 和 Selenium 在类中获取跨度

python - 使用 Gevents 异步生成函数

c# - 调用包含来自 MVC Controller 的异步调用的服务的正确模式

r - 如何在 Rselenium 中释放按键

c# - 尝试使用 C# 在 Windows 注册表中设置 DWORD 值时出错

c# - 高级 System.Transactions 调试

C# WinForm 内存泄漏

python - 如何将 AsyncIterable 转换为 asyncio Task