title: WPF / XAML: How do I execute threaded processes and prevent the main UI from being busy / freezing?
body: <p>I have a XAML application that serves as the UI for an automation.  The entire automation can take anywhere from 20-30 hours to fully execute so I created a Task class object that essentially wraps Thread methods (Start/Stop/Reset).</p>
  
  <p>However, when I run the automation method under the Task object, the XAML UI is busy and I cannot interact with the other controls, including the Pause button which toggles the Thread.Set() flag.</p>
  
  <p>There is another post
  <a href="https://stackoverflow.com/questions/1644874/prevent-ui-from-freezing-without-additional-threads">Prevent UI from freezing without additional threads</a></p>
  
  <p>where someone recommended the BackgroundWorker class this MSDN article mentions it is a bad idea to use this when if it manipulates objects in the UI, which mine does for purposes of displaying status counts:
  <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx</a></p>
  
  <p>Any idea around this?</p>
  
  <pre><code>    private void OnButtonStartAutomationClick(object sender, RoutedEventArgs e)
      {
          btnPauseAutomation.IsEnabled = true;
          Automation.Task AutomationThread = new Automation.Task(RunFullAutomation);
      }
  
      private void RunFullAutomation()
      {
          // do stuff that can take 20+ hours
          // threaded so I can utilize a pause button (block)
      }
  
  class Task
  {
      private ManualResetEvent _shutdownFlag = new ManualResetEvent(false);
      private ManualResetEvent _pauseFlag = new ManualResetEvent(true);
      private Thread _thread;
      private readonly Action _action;
  
      public Task(Action action)
      {
          _action = action;
      }
  
      public void Start()
      {
          ThreadStart ts = new ThreadStart(DoDelegatedMethod);
          _thread = new Thread(ts);            
          _thread.Start();
          _thread.Priority = ThreadPriority.Lowest;
      }
  
      public void Resume()
      {
          _pauseFlag.Set();
      }
  
      public void Stop()
      {
          _shutdownFlag.Set();
          _pauseFlag.Set();
          _thread.Join();
      }
  
      private void DoDelegatedMethod()
      {
          do
          {
              _action();
          }
          while (!_shutdownFlag.WaitOne(0));
      }
  }
  </code></pre>