C# 优化使用HttpClient和TPL验证代理的性能

C# 优化使用HttpClient和TPL验证代理的性能,c#,task-parallel-library,dotnet-httpclient,C#,Task Parallel Library,Dotnet Httpclient,我正在尝试使用HttpClient和TPL来验证一些代理地址。我正在使用像这样简单的东西,我已经设置ServicePointManager.DefaultConnectionLimit=100;在我开始之前 我发现的问题是,连续运行之间的结果差异很大。有时可能有4个有效的代理,然后再运行一秒钟,将得到194个有效代理。我担心也许我应该处理任务限制。这是我应该自己来做的吗 或者还有其他我应该尝试处理的问题吗 internal class Validator { private readon

我正在尝试使用HttpClient和TPL来验证一些代理地址。我正在使用像这样简单的东西,我已经设置ServicePointManager.DefaultConnectionLimit=100;在我开始之前

我发现的问题是,连续运行之间的结果差异很大。有时可能有4个有效的代理,然后再运行一秒钟,将得到194个有效代理。我担心也许我应该处理任务限制。这是我应该自己来做的吗

或者还有其他我应该尝试处理的问题吗

internal class Validator
{
    private readonly ConcurrentDictionary<string, long> _validatedProxyDic = new ConcurrentDictionary<string, long>();
    private async Task<Tuple<bool, long>> ValidateProxy(Tuple<string, string, string> tuple)
    {
        try
        {
            string proxy = tuple.Item1;
            string url = tuple.Item2;
            string pattern = tuple.Item3;

            var handler = new HttpClientHandler
            {
                CookieContainer = new CookieContainer(),
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
                Proxy = new WebProxy(proxy, true),
                UseProxy = true
            };

            var client = new HttpClient(handler);
            client.DefaultRequestHeaders.ExpectContinue = false;
            client.DefaultRequestHeaders.Add("User-Agent",
                "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)");
            client.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
            client.DefaultRequestHeaders.Add("Accept", "*/*");
            client.Timeout = TimeSpan.FromMilliseconds(10000);

            var stopWatch = Stopwatch.StartNew();
            var response = await client.GetAsync(url);
            var str = await response.Content.ReadAsStringAsync();

            if (str.Contains(pattern))
                _validatedProxyDic.TryAdd(proxy, stopWatch.ElapsedMilliseconds);

            return new Tuple<bool, long>(str.Contains(pattern), stopWatch.ElapsedMilliseconds);
        }
        catch (Exception ex)
        {

        }

        return new Tuple<bool, long>(false, -1);
    }

    public void Foo(IEnumerable<string> proxyList, string loginUrl, string keyword)
    {
        var taskList = new List<Task<Tuple<bool, long>>>();
        foreach (var proxy in proxyList)
        {
            var tuple = new Tuple<string, string, string>(proxy, loginUrl, keyword);
            var task = Task.Run(() => ValidateProxy(tuple));
            taskList.Add(task);
        }
        var result = Task.WhenAll(taskList).Result;

        var validatedProxySortedList = from pair in _validatedProxyDic orderby pair.Value ascending select pair;

        using (var sw = new StreamWriter("ProxyValidatedListSorted.txt"))
        {
            foreach (var proxy in validatedProxySortedList)
                sw.WriteLine(proxy.Key + "\t" + proxy.Value);
        }

        Console.WriteLine("Found {0} proxies.", validatedProxySortedList.Count());
    }
}

顺便说一句,我不知道为什么,但似乎设置了少量ServicePointManager.DefaultConnectionLimit。例如,2实际上为您提供了更有效的代理。ServicePointManager.DefaultConnectionLimit只有在您向同一服务器服务点发出多个请求时才有效。你这么做了吗?@svick:是的,我这么做了。我有多个线程,每个线程使用不同的代理来验证每个代理是否工作。然后,对于每个线程,我获取特定Url的页面内容,并检查返回的流是否包含给定的关键字。啊,我应该更仔细地阅读您的代码。你所有的代理都是匿名的吗?如果不是,可能是目标站点将此检测为拒绝服务尝试吗?@svick:是的。我所有的代理都是匿名的。