0

我有两个插件在第三方主机应用程序中工作。该主机有一个名为 的事件DocumentOpened

我从插件 A 和插件 B 订阅此事件。显然插件 A 和插件 B 彼此不认识。我想要实现的是在 B 处理其事件后再次将控制权交给插件 A。

Plugin A)

Host.DocumentOpened += SomeCodeA()


Plugin B)
Host.DocumentOpened += SomeCodeB()

现在不知何故,在插件 A 中执行一些东西!再次进入B后,我不知道如何将控制权返回给A!

所以让我们说在这一切完成之后调用 PluginA.Method() !

4

1 回答 1

1

为此,您可能需要某种方式让插件 A 和 B 相互通信。这里有一些方法,但可能还有其他方法:

事件等待句柄

一种相当简单的方法是使用系统范围的同步事件。两个插件都将创建一个同名的 EventWaitHandle。然后插件 A 可以创建一个等待事件的线程,插件 B 将设置该事件。如果插件 B 不存在,则永远不会引发该事件。这是一个系统范围的事件,因此如果主机的多个实例正在运行,则不会起作用,除非您执行诸如在事件名称中包含处理器 ID 之类的操作。

IPC/RPC 方法

进程之间可以使用多种通信方式:

  • 命名管道
  • 消息总线
  • 网络服务
  • Windows 通信基础

这将是一个更复杂的解决方案,但也会更通用。例如,它可以处理主机应用程序决定在单独的进程中运行插件,或者如果您想在插件之间传输更多数据。

共享装配

您可以创建两个插件都使用的程序集。这将允许您创建一个在两个插件之间共享的单例对象。像这样的东西:

public class PluginCommunication
{
    public event EventHandler MyEvent;
    public void RaiseEvent() => MyEvent?.Invoke(this, EventArgs.Empty);
    public static PluginCommunication PluginBEvent = new PluginCommunication();
}

插件 B 会调用PluginCommunication.PluginBEvent.RaiseEvent();,插件 A 会附加一个事件处理程序,例如PluginCommunication.PluginBEvent.MyEvent += PluginAEventHandler;

这种方法存在潜在的缺陷。如果您需要以任何方式更改程序集,您将面临插件 A 使用版本 1 和插件 B 使用版本 2 的风险,如果您不非常小心,这可能会以糟糕的方式结束。如果您不在主线程上执行所有操作,也可能会出现线程问题。

于 2020-06-26T14:44:57.967 回答