title: Best way to handle exception in multi task to call WCF operation
body: <p>I have implemented a service name <code>ExamClient</code> which have two operations one is <code>Ping</code> which return a basic <code>string</code> which mean service is available and one is <code>FindStudy</code> which search in DB it may take a long to be proceeded.</p>
  
  <p>In the other side I have several endpoints of <code>ExamClient</code> I wand to run <code>FindStudy</code> per end point by task so in a <code>Dispatcher</code> I have something like this:</p>
  
  <pre><code>public FindStudies_DTO_OUT FindStudies(FindStudies_DTO_IN findStudies_DTO_IN)
  {
      List&lt;Study_C&gt; ret = new List&lt;Study_C&gt;(); 
      List&lt;Task&gt; tasks = new List&lt;Task&gt;();
      foreach (var sp in Cluster)
      {
          string serviceAddress = sp.GetLibraryAddress(ServiceLibrary_C.PCM) + "/Exam.svc";
          var task = Task.Run(() =&gt;
          {
              ExamClient examClient = new ExamClient(serviceAddress.GetBinding(), new EndpointAddress(serviceAddress), Token);
              var ping = Task.Run(() =&gt;
              {
                  examClient.Ping();
              }); 
              if (!ping.Wait(examClient.Endpoint.Binding.OpenTimeout))
              {
                  Logging.Log(LoggingMode.Warning, "Timeout on FindStudies for:{0}, address:{1}", sp.Name, serviceAddress);
                  return new List&lt;Study_C&gt;(); // if return null then need to manage it on ret.AddRange(t.Result);
              }  
              return (examClient.FindStudies(findStudies_DTO_IN).Studies.Select(x =&gt;
              {
                  x.StudyInstanceUID = string.Format("{0}|{1}", sp.Name, x.StudyInstanceUID);
                  x.InstitutionName = sp.Name;
                  return x;
              }));
          });
          task.ContinueWith(t =&gt;
          {
              lock (ret)
              {
                  ret.AddRange(t.Result);
              }
          }, TaskContinuationOptions.OnlyOnRanToCompletion);
          task.ContinueWith(t =&gt;
          {
              Logging.Log(LoggingMode.Error, "FindStudies failed for :{0}, address:{1}, EXP:{2}", sp.Name, serviceAddress, t.Exception.ToString());
          }, TaskContinuationOptions.OnlyOnFaulted);
  
          tasks.Add(task);
      } 
      try
      {
          Task.WaitAll(tasks.ToArray());
      }
      catch (AggregateException aggEx)
      {
          foreach (Exception exp in aggEx.InnerExceptions)
          {
              Logging.Log(LoggingMode.Error, "Error while FindStudies EXP:{0}", exp.ToString());
          }
      }
  
      return new FindStudies_DTO_OUT(ret.Sort(findStudies_DTO_IN.SortColumnName, findStudies_DTO_IN.SortOrderBy));
  }
  </code></pre>
  
  <p>First I have to run <code>Ping</code> per end point to know connection is established
  after that <code>FindStudy</code>.</p>
  
  <p>if there are three end pints in <code>Cluster</code> six task be run in parallel mode, 3 for <code>Ping</code> and 3 for <code>FindStudy</code>.</p>
  
  <p>I think something is wrong with my code to handle exception nice...
  So what is the best way to implement this scenario ?</p>
  
  <p>thanks in advance.</p>