How do I use Dispatcher.BeginInvoke properly?

c#, dispatcher, winforms, wpf

Solution

That's because `Dispatcher.BeginInvoke`, though it may be the equivalent logical operation, doesn't return an `IAsyncResult`, it returns a `DispatcherOperation`. Have a look at this blog post and you'll see a good example on how the `Dispatcher` works. I have copied the relevant code example into here to ensure it exists later.

public Window1()
{
  InitializeComponent();

  CheckBox myCheckBox = new CheckBox();
  myCheckBox.Content = "A Checkbox";

  System.Threading.Thread thread = new System.Threading.Thread(
    new System.Threading.ThreadStart(
      delegate()
      {
        System.Windows.Threading.DispatcherOperation
          dispatcherOp = myCheckBox.Dispatcher.BeginInvoke(
          System.Windows.Threading.DispatcherPriority.Normal,
          new Action(
            delegate()
            {
              myCheckBox.IsChecked = true;
            }
        ));

        dispatcherOp.Completed += new EventHandler(dispatcherOp_Completed);
      }
  ));

  thread.Start();
}

void dispatcherOp_Completed(object sender, EventArgs e)
{
  Console.WriteLine("The checkbox has finished being updated!");
}

Take note to this line:

dispatcherOp.Completed += new EventHandler(dispatcherOp_Completed);

that's how you're going to know when it's completed - it's going to call back to you via that event.

Problem

I have searched almost everywhere on the internet, and I have googled so many times and found so many results, but I still can't find the solution to my problem. I am busy converting an old `WinForms` application to a new WPF application but I am having trouble with some of the commands. In the Winforms application they use `Control.BeginInvoke()` and store this in an IAsyncResult object. I have read that the `Dispatcher.BeginInvoke()` is the `WPF` equivalent to the `Control.BeginInvoke()` for `WinForms` but I get this error when I use Dispatcher.BeginInvoke(): "Cannot implicitly convert type 'System.Windows.Threading.DispatcherOperation' to 'System.IAsyncResult'. An explicit conversion exists (are you missing a cast?)". Any help will be appreciated. Here is the code that I am trying to convert. This is the original `WinForms` code. I am able to convert everything except the BeginInvoke part. ``` private eSkan.api.TeSkanAPI feSkanAPI = null; private void MessageFilter_AddRemove_Invoked(bool AddFilter, IMessageFilter Filter) { if (AddFilter){ Application.AddMessageFilter(Filter); } else { Application.RemoveMessageFilter(Filter); } } private void MessageFilter_AddRemove(bool AddFilter, IMessageFilter Filter) { { IAsyncResult sr = BeginInvoke((ESKAN_ADD_REMOVE_MESSAGEFILTER)MessageFilter_AddRemove_Invoked, AddFilter, Filter); sr.AsyncWaitHandle.WaitOne(2000); } } ``` Below is my code that I have converted so far including the BeginInvoke part that I am struggling with. ``` private void MessageFilter_AddRemove_Invoked(bool addFilter, System.Windows.Forms.IMessageFilter filter) { if (addFilter) { System.Windows.Forms.Application.AddMessageFilter(filter); } else { System.Windows.Forms.Application.RemoveMessageFilter(filter); } } private void MessageFilter_AddRemove(bool addFilter, System.Windows.Forms.IMessageFilter filter) { { IAsyncResult sr = System.Windows.Threading.Dispatcher.BeginInvoke((ESKAN_ADD_REMOVE_MESSAGEFILTER)MessageFilter_AddRemove_Invoked, addFilter, filter); sr.AsyncWaitHandle.WaitOne(2000); } } ``` If there are any other mistakes then please let me know. Thanks

Original source