2016-06-29 2 views
1

私はasp.net mvc-4 Webアプリケーションで作業しています。しかし、これら2つのアプローチを繰り返し使用することの違いは何ですかリスト上およびWebクライアント()を呼び出しを開始: -Parallel.ForEachとTask.Factory.StartNewを使用する主な違いは何ですか?

アプローチ-1

Parallel.ForEach(photos,new ParallelOptions { MaxDegreeOfParallelism = 7 }, p => 
          { 
     ResourceAccountListInfo resourceAccountListInfo = new ResourceAccountListInfo(); 
     WebClient wc = new WebClient();    

     var json = wc.DownloadString(p.url); 
     resourceAccountListInfo = JsonConvert.DeserializeObject<ResourceAccountListInfo>(json); 
     if (resourceAccountListInfo.operation.Details.CUSTOMFIELD.Count > 0) 
        { 
         List<CUSTOMFIELD> customfield = resourceAccountListInfo.operation.Details.CUSTOMFIELD.Where(a => 
           a.CUSTOMFIELDLABEL.ToLower() == "name" 
           ).ToList(); 
         if (customfield.Count == 1) 
         { 
          PMresourcesOnly.Add(resourceAccountListInfo.operation.Details); 

         } 

        } 
      //code goes here 
          }); 

アプローチ-2

foreach (Photo p in photos) 
         { 
      Task.Factory.StartNew(() => 
         { 
      ResourceAccountListInfo resourceAccountListInfo = new ResourceAccountListInfo(); 
      WebClient wc = new WebClient(); 

      var json = wc.DownloadString(p.url); 
      resourceAccountListInfo = JsonConvert.DeserializeObject<ResourceAccountListInfo>(json); 
        if (resourceAccountListInfo.operation.Details.CUSTOMFIELD.Count > 0) 
        { 
         List<CUSTOMFIELD> customfield = resourceAccountListInfo.operation.Details.CUSTOMFIELD.Where(a => 
           a.CUSTOMFIELDLABEL.ToLower() == "name" 
           ).ToList(); 
         if (customfield.Count == 1) 
         { 
          PMresourcesOnly.Add(resourceAccountListInfo.operation.Details); 

         } 

        } 
      //code goes here 
           }); 
         } 

をおかげ

+0

すべてのスレッドはすべて「resourceAccountListInfo」を置き換えますか?それは間違っていると思われる –

+0

違いは:Parallel.ForEachすべての "写真"が終了するまで待ってから、続けてください。 Task.Factory.StartNewでは、写真が終了したかどうかに関わらず、常に続行されます。 –

+0

@ScottChamberlain申し訳ありませんが、私の質問に関連するコードの一部だけを示しました..今、各反復の中にresourceAccountListInfoの余分な処理があります... –

答えて

1

Parallel.ForEachは、コレクションを繰り返し処理する際に便利です。 Task.Factory.StartNewはループ内で呼び出すことはできますが、ループ内で使用されることを示す固有のものはありません。 1つのタスクを開始するだけかもしれません。

Parallel.ForEachが並列動作の設定を前提とするので、それはあなたがその1つのループの範囲内で同時操作の数を指定することができたParallelOptionsを提供します。これは便利なことがあります。なぜなら、場合によっては、同時に実行される操作の数は気にしないかもしれませんが、それ以外の場合には可能性があります。並行タスクの数を制限するためにSemaphoreを使用することを説明しているthis answerを見てください。 MaxDegreeOfParallelismを設定すると、Semaphoreを使用するよりもはるかに簡単です。

また、Parallel.ForEachは、ParallelLoopResultを返します。これにより、ループ内のすべての操作が表示されます。同じような可視性を一連のタスクに取り入れるにはもう少し作業が必要です。複数のタスクを停止するのではなく、1つのメソッド呼び出しでループを停止することもできます。

+0

ですので、Tas.Factory.StartNewを使用する代わりにParallel.ForEachを使用しています。これは正しいですか?私の場合、Parallel.Foreachを使用する際に2番目の質問は、明示的にロックを使用してデータ破損がないことを確認する必要がありますか?これは必須ではありませんか? –

+0

並列処理をしたいコレクションを扱っている場合は 'Parallel.ForEach'を使います。さもなければ私は '仕事'を始めるかもしれません。同時に更新できない共有プロパティのように、並列タスクが必要なもので動作している場合は、ある種のロック(または並行性を管理する他の方法)を使用する必要があります。しかし、そのロックは、私が扱っているオブジェクトの中にある可能性が高いでしょう - ループ自体ではなく、並行性をサポートするように記述してください。 –

+0

「それ以外の場合、タスクを開始する可能性があります」という意味はどういう意味ですか? Parallel.forEachまたはTasksでロックを使用する必要がある場合は、詳細を教えてください。 –

関連する問題