title: Reporting progress in a console app using Parallel.ForEach
body: <p>I have the following code (below) that mostly works but I'm not getting the expected output.  I'm trying to get a line printed to the console for each item that is processed.  I want to show the percentage complete as the tasks complete.</p>
  
  <p>This is the output I get (the first few rows repeat).  I don't expect them to repeat so I know I've got something wrong.  No matter how many times I run this, the first few lines are the same.  Is it possible to get the output to show 1 --> 10 %, 2 --> 20 %, etc?</p>
  
  <pre><code>2 --&gt; 20 %  -- Bytes Read = 23971
  2 --&gt; 20 %  -- Bytes Read = 23971
  2 --&gt; 20 %  -- Bytes Read = 23971
  3 --&gt; 30 %  -- Bytes Read = 35909
  4 --&gt; 40 %  -- Bytes Read = 47872
  5 --&gt; 50 %  -- Bytes Read = 59824
  6 --&gt; 60 %  -- Bytes Read = 71775
  7 --&gt; 70 %  -- Bytes Read = 83746
  8 --&gt; 80 %  -- Bytes Read = 95701
  9 --&gt; 90 %  -- Bytes Read = 107686
  Elapsed Time: : 702
  Press Any Key
  </code></pre>
  
  <p>Here is the code I'm running</p>
  
  <pre><code>using RestSharp;
  using System;
  using System.Collections.Generic;
  using System.Threading.Tasks;
  
  namespace RestSharpAsyncTest
  {
      public class SomeItem
      {
          public int Id { get; set; }
          public long BytesRead { get; set; }
  
          public SomeItem(int i)
          {
              this.Id = i;
              this.BytesRead = 0;
          }
  
          public long ProcessItem()
          {
              var client = new RestClient("http://www.google.com");
              var request = new RestRequest("", Method.GET);
  
              var restResponse = client.Execute(request);
  
              return restResponse.RawBytes.Length;
          }
      }
  
      public class ProgressReport
      {
          public int Counter { get; set; } = 0;
          public long TotalBytesRead { get; set; }
          public int PercentComplete { get; set; }
      }
  
      class Program
      {
          private static async Task DoSomethingAsync(List&lt;SomeItem&gt; someItems, IProgress&lt;ProgressReport&gt; progress)
          {
              /// Set up the local progress reporter
              ProgressReport progressReport = new ProgressReport();
  
              System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
              watch.Start();
  
              await Task.Run(() =&gt;
              {
                  Parallel.ForEach(someItems, someItem =&gt;
                  {
                      long bytesRead = someItem.ProcessItem();
                      progressReport.Counter++;
                      progressReport.PercentComplete = (progressReport.Counter * 100) / someItems.Count;
                      progressReport.TotalBytesRead += bytesRead;
                      progress.Report(progressReport);                    
                  });
              });
  
              watch.Stop();
  
              Console.WriteLine("Elapsed Time: : {0}", watch.ElapsedMilliseconds);
          }
  
          static async Task Main(string[] args)
          {
              Progress&lt;ProgressReport&gt; pr = new Progress&lt;ProgressReport&gt;();
              pr.ProgressChanged += Pr_ProgressChanged;
  
              // Create some items
              List&lt;SomeItem&gt; someItems = new List&lt;SomeItem&gt;();
  
              for (int i = 1; i &lt; 11; i++)
                  someItems.Add(new SomeItem(i));
  
              await DoSomethingAsync(someItems, pr);
  
              Console.WriteLine("Press Any Key");
              Console.ReadKey();
          }
  
          private static void Pr_ProgressChanged(object sender, ProgressReport e)
          {
              Console.WriteLine($"{e.Counter } --&gt; { e.PercentComplete } %  -- Bytes Read = { e.TotalBytesRead }");
          }
      }
  }
  </code></pre>
  
  <p>EDIT: 
  I added the following but still end up with the same results.</p>
  
  <pre><code>public class Program
  {
      private static object locker = new object();
  </code></pre>
  
  <p>then</p>
  
  <pre><code>lock (locker)
  {
      progressReport.Counter++;
      progressReport.PercentComplete = (progressReport.Counter * 100) / someItems.Count;
      progressReport.TotalBytesRead += bytesRead;
      progress.Report(progressReport);
  }
  </code></pre>