在 C# 中,我可以检查事件是否有任何侦听器:
C# 示例:
public static event EventHandler OnClick;
if (OnClick != null)
OnClick(null, new EventArgs() );
在 C++/CLI 中,不需要检查事件是否为 null。
C++/CLI 示例:
delegate void ClickDelegate( Object^ sender, MyEventArgs^ e );
event ClickDelegate^ OnClick;
OnClick (sender, args);
但是,在我正在处理的项目中,如果没有侦听器,我不想构造 MyEventArgs 对象。
如何查明 OnClick 是否有 C++ 侦听器?
基于与 @BenVoigt 对 @svick 的原始答案和新答案的评论讨论有关 C++/CLI 事件的 MSDN 文章 http://msdn.microsoft.com/en-us/library/58cwt3zh.aspx#code-snippet-2,我创建了一个最小的示例来说明如何正确执行此操作。此代码在面向 .NET 4.5 的 Visual Studio 2013 CLR 项目模板中编译和运行。我尚未在其他运行时和目标上进行测试,但它仅使用基本的 .NET 组件。
TL;DR:
-
将支持字段设置为私有
-
锁定每个添加、删除和发起呼叫System::Threading::Monitor
-
使用标准事件处理程序约定:
void MyEventHandler(Object ^sender, MyEventArgs ^e);
-
Use +=
and -=
除非支持字段是nullptr
我的解决方案:
// compile with: /clr
#include "stdafx.h"
using namespace System;
using System::Threading::Monitor;
public delegate void MyDelegate(Object ^sender, EventArgs ^e);
ref class EventSource {
private:
MyDelegate ^myEvent;
Object ^eventLock;
public:
EventSource()
{
eventLock = gcnew Object();
}
event MyDelegate^ Event {
void add(MyDelegate^ handler) {
Monitor::Enter(eventLock);
if (myEvent == nullptr)
{
myEvent = static_cast<MyDelegate^> (
Delegate::Combine(myEvent, handler));
}
else
{
myEvent += handler;
}
Monitor::Exit(eventLock);
}
void remove(MyDelegate^ handler) {
Monitor::Enter(eventLock);
if (myEvent != nullptr)
{
myEvent -= handler;
}
Monitor::Exit(eventLock);
}
void raise(Object ^sender, EventArgs ^e) {
Monitor::Enter(eventLock);
if (myEvent != nullptr)
myEvent->Invoke(sender, e);
Monitor::Exit(eventLock);
}
}
void Raise()
{
Event(this, EventArgs::Empty);
}
};
public ref struct EventReceiver {
void Handler(Object ^sender, EventArgs ^e) {
Console::WriteLine("In event handler");
}
};
int main() {
EventSource ^source = gcnew EventSource;
EventReceiver ^receiver = gcnew EventReceiver;
// hook event handler
source->Event += gcnew MyDelegate(receiver, &EventReceiver::Handler);
// raise event
source->Raise();
// unhook event handler
source->Event -= gcnew MyDelegate(receiver, &EventReceiver::Handler);
// raise event, but no handlers
source->Raise();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)