1

次のプロセスを並列化するために、基本的に並列の方法で反復する関数があります。

  1. ウェブページを取得する
  2. HTML コードを解析する
  3. 結果を返し、結果コレクションに追加する

問題は、最初の実行に約 5 分、2 回目の実行に約 40 分かかることです。入力コレクションは変更されていないため、実行時間はほぼ同じです。何か案が?

GetPrices(int) を含めました。これが 2 回目に実行されると、netstat で 0 接続から開始されます (したがって、最初に使用可能な接続を使い果たすことはありません) が、5 接続までしか増加しません (最初の実行では 30 でした)。

また、返品コレクションをロックする必要があると思いますか?

    public Dictionary<int, Dictionary<int, double>> GetPrices(List<int> IDs)
    {
        Stopwatch web_time = new Stopwatch(), regex_time = new Stopwatch();
        Dictionary<int, Dictionary<int, double>> ret = new Dictionary<int, Dictionary<int, double>>();
        int aux_bkp = ServicePointManager.DefaultConnectionLimit;
        ParallelOptions pOptions = new ParallelOptions();

        ServicePointManager.DefaultConnectionLimit = 30;

        pOptions.MaxDegreeOfParallelism = 35;
        Parallel.ForEach(IDs, pOptions, ID=>
            {
                Dictionary<int, double> aux = GetPrices(ID);

                lock (ret)
                {
                    ret.Add(ID, new Dictionary<int, double>());
                    foreach (int kID in aux.Keys)
                    {
                        ret[mktID].Add(kID , aux[kID ]);
                    }
                }

            });

        ServicePointManager.DefaultConnectionLimit = aux_bkp;

        return ret;
    }
    public static Dictionary<int, double> GetPrices(int ID)
    {
        Stopwatch web_time = new Stopwatch(), regex_time = new Stopwatch();
        WebClient webclient = new WebClient();
        string resp;
        Dictionary<int, double> ret = new Dictionary<int, double>();
        bool success = false;
        int retries = 0;

        web_time.Start();
        while (!success)
            try
            {
                Debug.WriteLine(string.Format("Get HTML: ({1}) - ({0})", url, ID));

                resp = webclient.DownloadString(url);
                success = true;
                web_time.Stop();

                regex_time.Start();


                regex_time.Start();

                ret = ProcessHTML(resp, ID);
                regex_time.Stop();

            }
            catch (WebException e)
            {

                System.Net.HttpWebResponse aux;

                aux = e.Response as System.Net.HttpWebResponse;
                if (aux == null || aux.StatusCode != HttpStatusCode.NotFound)
                {
                    success = false;
                    retries++;
                    System.Threading.Thread.Sleep(new System.Random().Next(5000));
                    System.Diagnostics.Debug.WriteLine("HTTP Error - " + e.ToString());
                }
                else if (aux != null || aux.StatusCode == HttpStatusCode.NotFound)
                {
                    success = true;
                }


            }

        regex_time.Stop();
        return ret;
        }
4

0 に答える 0