跨应用域“可取消”事件

本文关键字:可取消 事件 应用 | 更新日期: 2023-09-27 17:55:18

我正在实现一个具有多个应用程序域的应用程序。大多数跨域通信都是使用事件机制完成的。一切都运行良好,除了那些 EventArgs 类包含带有 setter 的属性的事件。下面是 EventArgs 类的示例:

[Serializable]
public class CancelableEventArgs : EventArgs
{
    public bool Cancel { get; set; }
}

事件已成功触发,但如果我在第二个 AppDomain(订阅者)中设置 Cancel 属性,则在事件执行结束后,它不会持久化回第一个 AppDomain(发布者)。这种行为是有意为之,还是我错过了什么?

跨应用域“可取消”事件

有两种

类型的对象可以在 AppDomain 之间传递:可序列化对象和 MarshalByRefObject。

可序列化的对象(如帖子中的 EventArgs)在一个 AppDomain 中序列化为表示对象的一些字节,并在另一个 AppDomain 中反序列化。这意味着另一个应用程序域接收原始对象的副本。

此外,继承 MarshalByRefObject 的对象可以通过 AppDomain 之间引用传递。如果您继承 MarshalByRefObject 而不是使您的对象可序列化,它可能会解决您的问题。

仍然希望有一些更好的方法来做到这一点,但这是我使用的解决方法:

[Serializable]
public class CancelableEventArgs : EventArgs
{
    public MarshalByRefWrapper<bool> Cancel { get; set; }
}
public class MarshalByRefWrapper<T> : MarshalByRefObject
{
    public T Value { get; set; }
}

我不太完全了解它是如何工作的。但是有两项:

  1. 从 MarshalByRefObject 继承(用于跨域)
  2. EventArgs 的隐式运算符(用于 EventHandler)

在我这里,它转向传输数据,例如TypedDataSet和字符串。

public class MyEventArgs : MarshalByRefWrapper<EventArgs>
{
    public DataTable SystemState { get; set; }
    public string SystemString { get; set; }
}
public class MarshalByRefWrapper<T> : MarshalByRefObject
{
    public MarshalByRefWrapper()
    {
    }
    public MarshalByRefWrapper(T value)
    {
        Value = value;
    }
    public T Value { get; set; }
    public static implicit operator MarshalByRefWrapper<T>(T value)
    {
        return new MarshalByRefWrapper<T>(value);
    }
}