[英]How do I pass an argument to an event handler when the event handler is a delegate and doesn't include that argument?
[英]How to pass a delegate as an argument to subscribe as an event handler?
我有一个提供事件StkQuit
的外部应用程序。
我在静态类中订阅此事件,该类处理我的应用程序和[外部]应用程序之间的所有通信。 我想使用另一个位于我的表单类的处理程序订阅StkQuit
事件。
此处理程序将通知用户外部应用程序已关闭。 我想在名为SubscribeToStkQuit
的静态类中有一个泛型方法,它接受委托作为参数,并将该委托(指我的表单类中的处理程序) StkQuit
到StkQuit
事件。
这可能吗? 这是实现此类功能的最优雅/最简单的方法吗?
我的示例代码:
表格类
public delegate void dForceClose();
public void SubscribeToStkQuit(dForceClose forceClose)
{
UtilStk.SubscribeToStkQuit(forceClose = new dForceClose(ForceClose));
}
private void ForceClose()
{
MessageBox.Show("TEST");
}
静态类
private static AgUiApplication _stkUiApplication;
public static void SubscribeToStkQuit(Delegate subscribeHandler)
{
_stkUiApplication.OnQuit += subscribeHandler;
}
[更新]
根据评论,我已更新代码,如下所示:
public delegate void dForceClose(object sender, EventArgs e);
public void SubscribeToStkQuit(dForceClose forceClose)
{
UtilStk.SubscribeToStkQuit(forceClose = new dForceClose(ForceClose));
}
private void ForceClose(object sender, Eventargs e)
{
MessageBox.Show("TEST");
}
我仍然得到演员异常。 有任何想法吗 ??
[更新#2]
我仍然遇到这个问题。 在我的静态类中,当OnQuit
触发时,我已经有了一个处理程序:
private static AgUiApplication _stkUiApplication;
public static bool CheckThatStkIsAvailable()
{
object stkApplication = null;
try
{
stkApplication = Marshal.GetActiveObject(_stkProgId);
_stkUiApplication = stkApplication as AgUiApplication;
_stkUiApplication.OnQuit += StkQuit;
return true;
}
catch (Exception)
{
// handle this
}
}
private static void StkQuit()
{
_stkUiApplication.OnQuit -= StkQuit;
Marshal.FinalReleaseComObject(_stkUiApplication);
Marshal.FinalReleaseComObject(_stkRoot);
}
这很好用。 所以我想我会为_stkUiApplication创建一个公共属性,并以相同的方式从表单类订阅:
静态类
public static AgUiApplication StkUiApplication
{
get { return _stkUiApplication; }
}
表格类
private void SubscribeToStkQuit()
{
UtilStk.StkUiApplication.OnQuit += StkQuit;
}
private void StkQuit()
{
MessageBox("TEST");
}
如果使用实例方法订阅静态事件,则在处理静态事件之前不会对实例进行垃圾回收(除非您取消订阅)。
这将导致内存泄漏。
除此之外,你的代码的问题是,签名ForceClose()
不匹配_stkUiApplication.OnQuit
它需要ForceClose(object sender, SomeKindOfEventArgs e)
它应该是UtilStk.SubscribeToStkQuit(forceClose => (s, e){ForceClose();});
编辑:
您对外部应用的引用是静态的:
private static AgUiApplication _stkUiApplication;
所以它会在你的申请期间存在。 添加事件处理程序
_stkUiApplication.OnQuit
将引用传递给表单类实例上的方法。 此引用现在将在您的应用程序的生命周期中保留,因此不能进行垃圾回收。
要处理这种情况,要么在处理侦听对象时显式取消注册( - =)处理程序,要么使用静态处理程序处理静态事件。
我错误地认为你最初是在描述网络表单,这会改变一些事情(你可能只会实例化一个Form
),但无论如何都是如此。 这是一个很好的做法。
要解决当前问题:您需要输入传递给的参数:
public static void SubscribeToStkQuit(Delegate subscribeHandler)
{
_stkUiApplication.OnQuit += subscribeHandler;
}
是_stkUiApplication.OnQuit
的类型
就像是
public static void SubscribeToStkQuit(EventHandler<EventArgs> subscribeHandler)
{
_stkUiApplication.OnQuit += subscribeHandler;
}
然后你可以这样做:
public void SubscribeToStkQuit()
{
UtilStk.SubscribeToStkQuit((sender, args) => ForceClose(sender, args));
}
是的你可以!
但最好使用动作和函数,这些参数化在参数化方面都很灵活(所有这些都在System命名空间中)。
无论如何,我还有另一个建议:你为什么不使用事件访问器? 您可以在静态类中创建一个:
public event EventHandler Quit { add { _stkUiApplication.OnQuit += value; } remove { _stkUiApplication.OnQuit -= value; } }
关于操作和函数,这些也是委托,因此您可以将它们作为任何委托的输入参数随处使用。
也许您可以使用事件访问器并以.NET方式执行,不是吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.