WPF应用程序中的编组事件 [英] Marshalling events in WPF application

查看:121
本文介绍了WPF应用程序中的编组事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当您不知道创建被调用对象的线程时,我想知道如何在工作线程中封送回调.使用ISynchronizeInvoke接口非常简单-我使用了如下代码:

I was wondering about how to marshal callbacks from within the worker thread, when you don''t know the thread that created the object being called into. Using ISynchronizeInvoke interface was simple enough - I used code like:

class MyMultithreadClass {
  public event EventHandler MarshalledEvent;

  private void FireMarshalledEvent() {
    if (MarshalledEvent != null) {
      foreach (Delegate d in MarshalledEvent.GetInvocationList()) {
        if (d.Target is ISynchronizeInvoke && ((ISynchronizeInvoke)d.Target).InvokeRequired) {
          ((ISynchronizeInvoke)d.Target).Invoke(d, new object[] { this, EventArgs.Empty });
        }
        else
          ((EventHandler)d)(this, EventArgs.Empty);
      }
    }
  }
}



我想知道如何针对基于WPF的应用程序执行此类操作.我了解Dispatcher对象的用法,但是要获取特定线程的Dispatcher,您需要知道在其上创建对象的线程.
这样做的原因是多线程类正在进入一个库,并且调用者不必知道他们的调用是否要在工作线程上运行,也不必放入编组代码将是一个很好的选择.



I was wondering how to do this type of thing for a WPF based application. I understand the use of the Dispatcher object, but to get the Dispatcher for a particular thread, you need to know the thread the object was created on.
The reason for this is that the multithreaded class is going into a library, and it would be nice for the caller not to have to know if their call is to be run on a worker thread or not, and not to have to put marshalling code into every event handler.

推荐答案

我找到了解决方案.显然,任何需要Dispatcher的对象都将从DependencyObject类继承.这允许使用与上述相同的模式,仅使用DependencyObject而不是ISynchronizeInvoke,并使用CheckAccess()方法代替InvokeRequired属性.
I have found the solution. Apparently, any object that requires a Dispatcher inherits from the DependencyObject class. This allows for the same pattern as above, only using DependencyObject instead of ISynchronizeInvoke, and CheckAccess() method instead of InvokeRequired property.
if (MarshalledEvent != null) {
  foreach (Delegate d in MarshalledEvent.GetInvocationList()) {
    if (d.Target is DependencyObject && ((DependencyObject)d.Target).Dispatcher.CheckAccess() == false)
      ((DependencyObject)d.Target).Dispatcher.Invoke(d, new object[] { this, EventArgs.Empty });
    else
      d.DynamicInvoke(this, EventArgs.Empty);
  }
}


这篇关于WPF应用程序中的编组事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆