【问题标题】:multiple parallel execution of WebClient as Task (TPL)WebClient 作为任务 (TPL) 的多个并行执行
【发布时间】:2012-11-22 04:36:37
【问题描述】:

我正在测试 IWebDriverWebClient 的并行执行。 (如果有性能差异以及它有多大)

在我设法这样做之前,我遇到了简单的 WebClient-Parallel 调用问题。

似乎还没有执行,我确实在AgilityPacDocExtraction 上放了刹车点 在WebClient.DownloadString(URL)的具体行

但程序退出 而不是调试 Step Into 可以显示 yeald 字符串。

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

主要执行:

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

   }

模式/动作选择器

    enum Action
    {
        Act1, Act2
    }

实际执行

    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;

        }
     }

这里没有包含 WebClientIWebDriver(由 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;
    }
}
}

问题是我看不到文件中应该通过从 WebClient 提取的值来更改的任何内容,而且在调试模式下我无法进入上面代码中注释的行。我在这里做错了什么?

【问题讨论】:

    标签: c# enums task-parallel-library webclient


    【解决方案1】:

    上面的代码中没有定义函数Download(url, htmlDictionary),一个可能的版本是:

    private static void Download(string url, ConcurrentDictionary<string, string> htmlDictionary)
    {
        using (var webClient = new SmartWebClient())
        {
            htmlDictionary.TryAdd(url, webClient.DownloadString(url));
        }
    }
    

    ... 上面的代码似乎是另一个 Stack Overflow 帖子的副本。参考见Retrieve a string containing html Document source using Task parallel

    【讨论】:

      【解决方案2】:

      我已经设法通过使用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;
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-08
        • 2021-10-15
        相关资源
        最近更新 更多