title: Async/Await with a WinForms ProgressBar
body: <p>I've gotten this type of thing working in the past with a BackgroundWorker, but I want to use the new async/await approach of .NET 4.5. I may be barking up the wrong tree. Please advise.</p>
  
  <p><strong>Goal</strong>: Create a component that will do some long-running work and show a modal form with a progress bar as it's doing the work. The component will get the handle to a window to block interaction while it's executing the long-running work.</p>
  
  <p><strong>Status</strong>: See the code below. I thought I was doing well until I tried interacting with the windows. If I leave things alone (i.e. don't touch!), everything runs "perfectly", but if I do so much as click on either window the program hangs after the long-running work ends. Actual interactions (dragging) are ignored as though the UI thread is blocked.</p>
  
  <p><strong>Questions</strong>: Can my code be fixed fairly easily? If so, how? Or, should I be using a different approach (e.g. BackgroundWorker)?</p>
  
  <p><strong>Code</strong> (Form1 is a standard form with a ProgressBar and a public method, UpdateProgress, that sets the ProgressBar's Value):</p>
  
  <pre><code>using System;
  using System.Diagnostics;
  using System.Threading;
  using System.Threading.Tasks;
  using System.Windows.Forms;
  
  namespace ConsoleApplication1
  {
  class Program
  {
      static void Main(string[] args)
      {
          Console.WriteLine("Starting..");
          var mgr = new Manager();
          mgr.GoAsync();
          Console.WriteLine("..Ended");
          Console.ReadKey();
      }
  }
  
  class Manager
  {
      private static Form1 _progressForm;
  
      public async void GoAsync()
      {
          var owner = new Win32Window(Process.GetCurrentProcess().MainWindowHandle);
          _progressForm = new Form1();
          _progressForm.Show(owner);
  
          await Go();
  
          _progressForm.Hide();
      }
  
      private async Task&lt;bool&gt; Go()
      {
          var job = new LongJob();
          job.OnProgress += job_OnProgress;
          job.Spin();
          return true;
      }
  
      void job_OnProgress(int percent)
      {
          _progressForm.UpdateProgress(percent);
      }
  }
  
  class LongJob
  {
      public event Progressed OnProgress;
      public delegate void Progressed(int percent);
  
      public void Spin()
      {
          for (var i = 1; i &lt;= 100; i++)
          {
              Thread.Sleep(25);
              if (OnProgress != null)
              {
                  OnProgress(i);
              }
          }
      }
  }
  
  class Win32Window : IWin32Window
  {
      private readonly IntPtr _hwnd;
      public Win32Window(IntPtr handle)
      {
          _hwnd = handle;
      }
      public IntPtr Handle
      {
          get
          {
              return _hwnd;
          }
      }
  }
  }
  </code></pre>