C# WebClient作为任务(TPL)的多个并行执行

C# WebClient作为任务(TPL)的多个并行执行,c#,enums,task-parallel-library,webclient,C#,Enums,Task Parallel Library,Webclient,我正在测试IWebDrivervsWebClient的并行执行。 (如果存在性能差异以及差异有多大) 在我设法做到这一点之前,我对简单的WebClient并行调用有问题 似乎还没有执行,我确实在AgilityPacDocExtraction 在WebClient.DownloadString(URL) 但该计划退出了 而不是调试单步执行可以显示yeald字符串 计划是为所有需要采取的行动提供单一的方法, 通过每个操作的“模式”选择器, 然后使用一个简单的foreach,它将迭代所有可用的枚举值-

我正在测试
IWebDriver
vs
WebClient
的并行执行。 (如果存在性能差异以及差异有多大)

在我设法做到这一点之前,我对简单的WebClient并行调用有问题

似乎还没有执行,我确实在
AgilityPacDocExtraction
WebClient.DownloadString(URL)

但该计划退出了 而不是调试
单步执行
可以显示yeald字符串

计划是为所有需要采取的行动提供单一的方法, 通过每个操作的“模式”选择器, 然后使用一个简单的
foreach
,它将迭代所有可用的
枚举值
-模式

主要的解释是:

   static void Main(string[] args)
   {
        EnumForEach<Action>(Execute);
        Task.WaitAll();
   }
   public static void EnumForEach<Mode>(Action<Mode> Exec)
   {

            foreach (Mode mode in Enum.GetValues(typeof(Mode)))
            {
                Mode Curr = mode;

                Task.Factory.StartNew(() => Exec(Curr) );
            }

   }
实际执行

    static  BrowsresFactory.IeEngine IeNgn = new BrowsresFactory.IeEngin();
    static string 
        FlNm = Environment.CurrentDirectory,
        URL = "",
        TmpHtm ="";


   static void Execute(Action Exc)
   {


        switch (Exc)
        {
            case Action.Act1:
                break;

            case Action.Act2:
                URL  = "UrlofUrChoise here...";
                FlNm += "\\TempHtm.htm";
                TmpHtm = IeNgn.AgilityPacDocExtraction(URL).GetElementbyId("Dv_Main").InnerHtml;
                File.WriteAllText(FlNm, TmpHtm);
                break;

        }
     }
包含
WebClient
IWebDriver
(由selenium提供)的类未包含在此处,因此在本文中不会占用更多空间,所有这些内容目前都不相关

class BrowsresFactory
{
    public class IeEngine
{

    private WebClient WC = new WebClient();
    private string tmpExtractedPageValue = "";
    private HtmlAgilityPack.HtmlDocument retAglPacHtmDoc = new HtmlAgilityPack.HtmlDocument();

    public HtmlAgilityPack.HtmlDocument AgilityPacDocExtraction(string URL)
    {
                WC.Encoding = Encoding.GetEncoding("UTF-8");
                tmpExtractedPageValue = WC.DownloadString(URL); //<--- tried to break here
                retAglPacHtmDoc.LoadHtml(tmpExtractedPageValue);
                return retAglPacHtmDoc;
    }
}
}
类浏览工厂
{
公共级发动机
{
private WebClient WC=新WebClient();
私有字符串tmpExtractedPageValue=“”;
私有HtmlAgilityPack.HtmlDocument retAglPacHtmDoc=新的HtmlAgilityPack.HtmlDocument();
公共HtmlAgilityPack.HtmlDocument AgilityPacDocExtraction(字符串URL)
{
WC.Encoding=Encoding.GetEncoding(“UTF-8”);

tmpExtractedPageValue=WC.DownloadString(URL);//我通过使用
WebClient
解决了这个问题,我认为这比
WebDriver
需要更少的资源,如果是这样的话,也意味着需要更少的时间

代码如下:

public void StartEngins()
{
    const string URL_Dollar = "URL_Dollar";
    const string URL_UpdateUsersTimeOut = "URL_UpdateUsersTimeOut";


    var urlList = new Dictionary<string, string>();
    urlList.Add(URL_Dollar, "http://bing.com");
    urlList.Add(URL_UpdateUsersTimeOut, "http://localhost:..../.......aspx");


    var htmlDictionary = new ConcurrentDictionary<string, string>();
    Parallel.ForEach(
                    urlList.Values,
                    new ParallelOptions { MaxDegreeOfParallelism = 20 },
                    url => Download(url, htmlDictionary)
                    );
    foreach (var pair in htmlDictionary)
    {
        ///Process(pair);
        MessageBox.Show(pair.Value);
    }
}

public class SmartWebClient : WebClient
{
    private readonly int maxConcurentConnectionCount;

    public SmartWebClient(int maxConcurentConnectionCount = 20)
    {

        this.maxConcurentConnectionCount = maxConcurentConnectionCount;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        var httpWebRequest = (HttpWebRequest)base.GetWebRequest(address);
        if (httpWebRequest == null)
        {
            return null;
        }

        if (maxConcurentConnectionCount != 0)
        {
            httpWebRequest.ServicePoint.ConnectionLimit = maxConcurentConnectionCount;
        }

        return httpWebRequest;
    }

}
public void StartEngins()
{
常量字符串URL\u-Dollar=“URL\u-Dollar”;
常量字符串URL\u UpdateUsersTimeOut=“URL\u UpdateUsersTimeOut”;
var urlist=newdictionary();
添加(URL\u美元,“http://bing.com");
添加(URL\u UpdateUsersTimeOut,“http://localhost:..../.......aspx");
var htmlDictionary=新的ConcurrentDictionary();
并行ForEach(
urlList.Values,
新的并行选项{MaxDegreeOfParallelism=20},
url=>下载(url,htmlDictionary)
);
foreach(htmlDictionary中的var对)
{
///过程(对);
MessageBox.Show(pair.Value);
}
}
公共类SmartWebClient:WebClient
{
私有只读int-maxConcurentConnectionCount;
公共SmartWebClient(int-MaxConcurrentConnectionCount=20)
{
this.maxConcurentConnectionCount=maxConcurentConnectionCount;
}
受保护的覆盖WebRequest GetWebRequest(Uri地址)
{
var httpWebRequest=(httpWebRequest)base.GetWebRequest(address);
if(httpWebRequest==null)
{
返回null;
}
如果(MaxConcurrentConnectionCount!=0)
{
httpWebRequest.ServicePoint.ConnectionLimit=maxConcurentConnectionCount;
}
返回httpWebRequest;
}
}

我通过使用
WebClient
解决了这个问题,我认为这比
WebDriver
需要更少的资源,如果这是真的,也意味着所需的时间更少

代码如下:

public void StartEngins()
{
    const string URL_Dollar = "URL_Dollar";
    const string URL_UpdateUsersTimeOut = "URL_UpdateUsersTimeOut";


    var urlList = new Dictionary<string, string>();
    urlList.Add(URL_Dollar, "http://bing.com");
    urlList.Add(URL_UpdateUsersTimeOut, "http://localhost:..../.......aspx");


    var htmlDictionary = new ConcurrentDictionary<string, string>();
    Parallel.ForEach(
                    urlList.Values,
                    new ParallelOptions { MaxDegreeOfParallelism = 20 },
                    url => Download(url, htmlDictionary)
                    );
    foreach (var pair in htmlDictionary)
    {
        ///Process(pair);
        MessageBox.Show(pair.Value);
    }
}

public class SmartWebClient : WebClient
{
    private readonly int maxConcurentConnectionCount;

    public SmartWebClient(int maxConcurentConnectionCount = 20)
    {

        this.maxConcurentConnectionCount = maxConcurentConnectionCount;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        var httpWebRequest = (HttpWebRequest)base.GetWebRequest(address);
        if (httpWebRequest == null)
        {
            return null;
        }

        if (maxConcurentConnectionCount != 0)
        {
            httpWebRequest.ServicePoint.ConnectionLimit = maxConcurentConnectionCount;
        }

        return httpWebRequest;
    }

}
public void StartEngins()
{
常量字符串URL\u-Dollar=“URL\u-Dollar”;
常量字符串URL\u UpdateUsersTimeOut=“URL\u UpdateUsersTimeOut”;
var urlist=newdictionary();
添加(URL\u美元,“http://bing.com");
添加(URL\u UpdateUsersTimeOut,“http://localhost:..../.......aspx");
var htmlDictionary=新的ConcurrentDictionary();
并行ForEach(
urlList.Values,
新的并行选项{MaxDegreeOfParallelism=20},
url=>下载(url,htmlDictionary)
);
foreach(htmlDictionary中的var对)
{
///过程(对);
MessageBox.Show(pair.Value);
}
}
公共类SmartWebClient:WebClient
{
私有只读int-maxConcurentConnectionCount;
公共SmartWebClient(int-MaxConcurrentConnectionCount=20)
{
this.maxConcurentConnectionCount=maxConcurentConnectionCount;
}
受保护的覆盖WebRequest GetWebRequest(Uri地址)
{
var httpWebRequest=(httpWebRequest)base.GetWebRequest(address);
if(httpWebRequest==null)
{
返回null;
}
如果(MaxConcurrentConnectionCount!=0)
{
httpWebRequest.ServicePoint.ConnectionLimit=maxConcurentConnectionCount;
}
返回httpWebRequest;
}
}

上述代码中未定义下载功能(url,htmlDictionary)
,一个可能的版本是:

private static void Download(string url, ConcurrentDictionary<string, string> htmlDictionary)
{
    using (var webClient = new SmartWebClient())
    {
        htmlDictionary.TryAdd(url, webClient.DownloadString(url));
    }
}
私有静态无效下载(字符串url,ConcurrentDictionary htmlDictionary)
{
使用(var webClient=new SmartWebClient())
{
htmlDictionary.TryAdd(url,webClient.DownloadString(url));
}
}

…上述代码似乎是另一个堆栈溢出帖子的副本。有关参考信息,请参阅上述代码中未定义函数
下载(url,htmlDictionary)
,一个可能的版本是:

private static void Download(string url, ConcurrentDictionary<string, string> htmlDictionary)
{
    using (var webClient = new SmartWebClient())
    {
        htmlDictionary.TryAdd(url, webClient.DownloadString(url));
    }
}
私有静态无效下载(字符串url,ConcurrentDictionary htmlDictionary)
{
使用(var webClient=new SmartWebClient())
{
htmlDictionary.TryAdd(url,webClient.DownloadString(url));
}
}
…以上代码似乎是另一个堆栈溢出帖子的副本。有关参考信息,请参阅