title: are there any drawbacks or risks of using Parallel.Foreach with WebClient() inside my asp.net mvc web application
body: <p>I am working on an asp.net MVC-5 web application, and based on some articles i read that i should not use Parallel methods inside web servers and inside .net web applications espically.
  now in my case i have around 1,500 <code>WebClient()</code> calls that i need to issue inside a foreach, and then deserialize the return json object from the <code>WebClient()</code> calls. my original code before using <code>Parallel.Foreach</code> was as follow, which took around <strong>15</strong> minutes to complete:-</p>
  
  <pre><code>    public async Task &lt;List&lt;Details2&gt;&gt; Get()
              {       
  
                try
                  {
  
                      using (WebClient wc = new WebClient()) 
                      {
                          string url = currentURL + "resources?AUTHTOKEN=" + pmtoken;
                          var json = await wc.DownloadStringTaskAsync(url);
                          resourcesinfo = JsonConvert.DeserializeObject&lt;ResourcesInfo&gt;(json);
  
                      }
  
  
                      ForEach( var c in resourcesinfo.operation.Details)
                     {
  
                          ResourceAccountListInfo resourceAccountListInfo = new ResourceAccountListInfo();
                          using (WebClient wc = new WebClient()) 
                          {
  
                              string url = currentURL + "resources/" + c.RESOURCEID + "/accounts?AUTHTOKEN=" + pmtoken;
                              string tempurl = url.Trim();
  
  
  
                              var json =  await wc.DownloadStringTaskAsync(tempurl);
                              resourceAccountListInfo = JsonConvert.DeserializeObject&lt;ResourceAccountListInfo&gt;(json);
  
  
                          }
  
                     if (resourceAccountListInfo.operation.Details.CUSTOMFIELD.Count &gt; 0)
                      {
                          List&lt;CUSTOMFIELD&gt; customfield = resourceAccountListInfo.operation.Details.CUSTOMFIELD.Where(a =&gt;
                                   a.CUSTOMFIELDLABEL.ToLower() == "name"
                                  ).ToList();
                          if (customfield.Count == 1)
                          {
                              PMresourcesOnly.Add(resourceAccountListInfo.operation.Details);
  
                          }
  
                      }
  
                     }//end of foreach             
  
                      return PMresourcesOnly.ToList();
  
                  }
                  catch (Exception e)
                  {
                  }
                  return new List&lt;Details2&gt;();
              }
  </code></pre>
  
  <p>now i did the following modifications :-</p>
  
  <ul>
  <li>i replace <code>foreach</code> with <code>Parallel.ForEach</code> </li>
  <li><p>since i should not use async methods inside <code>Parallel.ForEach</code> so i chnage the <code>DownloadStringTaskAsync</code> to  <code>DownloadString</code> inside the <code>Parallel.Foreach</code> :-</p>
  
  <pre><code>public async Task &lt;List&lt;Details2&gt;&gt; Get()
          {
  
  
  
              try
              {
  
                  using (WebClient wc = new WebClient()) 
                  {
                      string url = currentURL + "resources?AUTHTOKEN=" + pmtoken;
                      var json = await wc.DownloadStringTaskAsync(url);
                      resourcesinfo = JsonConvert.DeserializeObject&lt;ResourcesInfo&gt;(json);
  
                  }
  
  
                  Parallel.ForEach(resourcesinfo.operation.Details, new ParallelOptions { MaxDegreeOfParallelism = 7 }, (c) =&gt;
                  {
  
                      ResourceAccountListInfo resourceAccountListInfo = new ResourceAccountListInfo();
                      using (WebClient wc = new WebClient()) 
                      {
  
                          string url = currentURL + "resources/" + c.RESOURCEID + "/accounts?AUTHTOKEN=" + pmtoken;
                          string tempurl = url.Trim();
  
  
  
                          var json =  wc.DownloadString(tempurl);
                          resourceAccountListInfo = JsonConvert.DeserializeObject&lt;ResourceAccountListInfo&gt;(json);
  
  
                      }
  
                  if (resourceAccountListInfo.operation.Details.CUSTOMFIELD.Count &gt; 0)
                  {
                      List&lt;CUSTOMFIELD&gt; customfield = resourceAccountListInfo.operation.Details.CUSTOMFIELD.Where(a =&gt;
                               a.CUSTOMFIELDLABEL.ToLower() == "name"
                              ).ToList();
                      if (customfield.Count == 1)
                      {
                          PMresourcesOnly.Add(resourceAccountListInfo.operation.Details);
  
                      }
  
                  }
  
  
  
                  });//end of foreach
  
  
  
  
              return PMresourcesOnly.ToList();
  
              }
              catch (Exception e)
              {
              }
              return new List&lt;Details2&gt;();
          }
  </code></pre></li>
  </ul>
  
  <p>now when i use the <code>Parallel.Foreach</code> the execution time was reduced from <strong>15</strong> minutes to around <strong>7</strong> minutes. but i am a bit confused if my second method is valid , so can anyone adivce on these questions (or any question):-</p>
  
  <ol>
  <li><p>is using <code>Parallel.Foreach</code> with <code>Webclient()</code> a valid approach to follow ? or i should avoid using Parallel methods inside .net and web applications?</p></li>
  <li><p>when using <code>Parallel.Foreach</code> could i face any problem such as that the <code>return PMresourcesOnly.ToList();</code> is return to the client while there are still some <code>wc.DownloadString(tempurl);</code> that did not complete?</p></li>
  <li><p>if i want to compare the 2 methods (Parallel.Foreach &amp; Foreach) will the result be the same ?</p></li>
  <li><p>on some online articles they use <code>Task.Factory.StartNew(()</code> instead of using <code>Parallel.foreach</code> so what are the main differences between them ? </p></li>
  </ol>
  
  <p><strong>EDIT</strong>
  I tried defining the <code>SemaphoreSlim</code> as follow:-</p>
  
  <pre><code>public async Task &lt;List&lt;Details2&gt;&gt; Get()
  {
  SemaphoreSlim throttler = new SemaphoreSlim(initialCount: 15);       
    try
    {
  //code goes here
  
  var tasks = resourcesinfo.operation.Details.Select(c =&gt; TryDownloadResourceAsync(c.RESOURCEID,throttler)).ToList();
  }
  </code></pre>
  
  <p>///---</p>
  
  <pre><code>private async Task&lt;Details2&gt; TryDownloadResourceAsync(string resourceId, SemaphoreSlim throttler)
          {
              await throttler.WaitAsync();
  try
              {
                  using (WebClient wc = new WebClient()) //get the tag , to check if there is a server with the same name &amp; tag..
                  {}
               }
   finally
              {
                  throttler.Release();
              }
  </code></pre>