title: Is there any way to use Dispatcher on a non WPF thread ; new to multi threading
body: <p>Why does this not work?</p>
  
  <p>What I am trying to do:
  I need a way to run specific methods in a specific thread that lives on till the end of the program.</p>
  
  <p>My other possible options:
  As I understand a possible way to do it would be to implement a queue. Into which I could push in methods I want to be run in the specific thread. In the specific thread, I would be spinning and sleeping / monitor.pulse to see if there are delegates waiting to be run in the queue.</p>
  
  <p>My objective:
  Is to avoid all the hardwork to create the delegate queue, maintain lock etc. It appears that a ready made solution exists in the WPF world called Dispatcher. WPF controls mostly inherit from DispatcherObject and somehow the whole thing works. What do I have to do to get this work?</p>
  
  <pre><code>using System;
  using System.Threading;
  using System.Windows.Threading;
  
  namespace ThreadingTrials
  {
      class Program
      {
          [STAThread]
          static void Main(string[] args)
          {
              Thread.CurrentThread.Name = "mainThread";
              Engine engine = new Engine();
              Console.WriteLine("initializing SpecialEngine from {0}", Thread.CurrentThread.Name);
              engine.initialize();
              engine.doWork();
          }
      }
      class Engine:DispatcherObject
      {
          private EventWaitHandle InitializationComplete;
          private EventWaitHandle newWorkComplete;
          //private Dispatcher dispatcher;
          public Engine()
          {
  
          }
          public void initialize()
          {
              InitializationComplete = new EventWaitHandle(false, EventResetMode.ManualReset);
              Thread thread = new Thread(new ParameterizedThreadStart((hwnd)=&gt;
              {
                  InitializeSpecialEngineObject();
                  while (true) ;
              }));
              thread.Name = "Special Engine Thread";
  
              thread.SetApartmentState(ApartmentState.STA);
              thread.Priority = ThreadPriority.Normal;
              thread.Start();
              Console.WriteLine("waiting for initialize at {0}", Thread.CurrentThread.Name);
              InitializationComplete.WaitOne();
          }
          private void InitializeSpecialEngineObject()
          {
              Console.WriteLine("doing initialization at {0}", Thread.CurrentThread.Name);
              Thread.Sleep(500);
              //dispatcher = Dispatcher.CurrentDispatcher;
              InitializationComplete.Set();
          }
  
          internal void doWork()
          {
              newWorkComplete = new EventWaitHandle(false, EventResetMode.AutoReset);
              //Dispatcher.Thread.Suspend();
              Dispatcher.Invoke((SendOrPostCallback)delegate
                  {
                      Console.WriteLine("dispatched to {0}", Thread.CurrentThread.Name);
                      Thread.Sleep(500);
                      newWorkComplete.Set();
                  },DispatcherPriority.Background, null);
              Dispatcher.Thread.Resume();
              Console.WriteLine("waiting for new work to complete at {0}", Thread.CurrentThread.Name);
              newWorkComplete.WaitOne();
          }
          private void doingWork()
          {
              Console.WriteLine("Doing work in {0}", Thread.CurrentThread.Name);
  
              Thread.Sleep(500);
          }
      }
  }
  </code></pre>
  
  <p>Thanks for the input.
  Fair enough. It was actually very little work to make a simple worker thread that waits for an event signifying a new task in queue of void() delegates, and runs them as they become available. I copied most of the code from a website online... Sorry lost reference. I had done it on that day, and should have edited this post earlier.</p>
  
  <pre><code>using System;
  using System.Threading;
  using System.Collections.Generic;
  
  class ProducerConsumerQueue : IDisposable
  {
      EventWaitHandle _wh = new AutoResetEvent(false);
      Thread _worker;
      readonly object _locker = new object();
      Queue&lt;Action&gt; _tasks = new Queue&lt;Action&gt;();
  
      public delegate void Action();
  
      public ProducerConsumerQueue()
      {
          _worker = new Thread(Work);
          _worker.Start();
      }
  
      public void EnqueueTask(Action work)
      {
          lock (_locker) _tasks.Enqueue(work);
          _wh.Set();
      }
  
      public void Dispose()
      {
          EnqueueTask(null);     // Signal the consumer to exit.
          _worker.Join();         // Wait for the consumer's thread to finish.
          _wh.Close();            // Release any OS resources.
      }
  
      void Work()
      {
          while (true)
          {
              Action task = null;
              lock (_locker)
                  if (_tasks.Count &gt; 0)
                  {
                      task = _tasks.Dequeue();
                      if (task == null) return;
                  }
              if (task != null)
              {
                  task.Invoke();
              }
              else
                  _wh.WaitOne();         // No more tasks - wait for a signal
          }
      }
  
  }
  class Program
  {
      static void Main()
      {
          using (ProducerConsumerQueue q = new ProducerConsumerQueue())
          {
              q.EnqueueTask(delegate 
              {
                  Console.WriteLine("Performing task: Hello");
                  Thread.Sleep(1000);  // simulate work...
              });
              for (int i = 0; i &lt; 10; i++) q.EnqueueTask(delegate 
              {
                  Console.WriteLine("Performing task: "+ i);
                  Thread.Sleep(1000);  // simulate work...
              });
              q.EnqueueTask(delegate 
              {
                  Console.WriteLine("Performing task: Goodbye!");
                  Thread.Sleep(1000);  // simulate work...
              });
          }
  
          // Exiting the using statement calls q's Dispose method, which
          // enqueues a null task and waits until the consumer finishes.
      }
  }
  </code></pre>