wpf 如何正确使用 Dispatcher.BeginInvoke?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15926310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:33:11  来源:igfitidea点击:

How do I use Dispatcher.BeginInvoke properly?

c#wpfwinformsdispatcher

提问by GANDA1F

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 WinFormsapplication 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 WPFequivalent to the Control.BeginInvoke()for WinFormsbut I get this error when I use

我正忙于将旧WinForms应用程序转换为新的 WPF 应用程序,但我在使用某些命令时遇到了问题。在 Winforms 应用程序中,他们使用它Control.BeginInvoke()并将其存储在 IAsyncResult 对象中。我已经读到Dispatcher.BeginInvoke()theWPF相当于Control.BeginInvoke()forWinForms但我在使用时收到此错误

Dispatcher.BeginInvoke(): "Cannot implicitly convert type 'System.Windows.Threading.DispatcherOperation' to 'System.IAsyncResult'. An explicit conversion exists (are you missing a cast?)".

Dispatcher.BeginInvoke():“无法将类型‘System.Windows.Threading.DispatcherOperation’隐式转换为‘System.IAsyncResult’。存在显式转换(您是否缺少演员表?)”。

Any help will be appreciated.

任何帮助将不胜感激。

Here is the code that I am trying to convert. This is the original WinFormscode. I am able to convert everything except the BeginInvoke part.

这是我试图转换的代码。这是原始WinForms代码。我能够转换除 BeginInvoke 部分之外的所有内容。

    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.

下面是我到目前为止转换的代码,包括我正在努力处理的 BeginInvoke 部分。

    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

谢谢

回答by Mike Perrenoud

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 postand you'll see a good example on how the Dispatcherworks. I have copied the relevant code example into here to ensure it exists later.

那是因为Dispatcher.BeginInvoke,虽然它可能是等效的逻辑运算,但它不返回IAsyncResult,而是返回DispatcherOperation。看看这篇博客文章,你会看到一个很好的例子,说明它是如何Dispatcher工作的。我已将相关代码示例复制到此处以确保以后存在。

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.

这就是您将如何知道它何时完成 - 它会通过该事件回电给您。