[英]C# EventHandler invoke doesn't always work
我有一个带有以下代码的类:
public delegate void EventHandler(HMIEventArgs e);
public event EventHandler OnEvent;
private void ReadReg(RegisterMap register)
{
if (!_hmiConnected) return;
var eventArgs = new HMIEventArgs();
var handler = OnEvent;
try
{
byte slaveId = 1;
ushort startAddress = register.Register;
eventArgs.Event = Events.GotData;
eventArgs.IPAddress = _hostname;
eventArgs.Name = register.FriendlyName;
ushort[] val = _master.ReadHoldingRegisters(slaveId, startAddress, 1);
eventArgs.Data = val[0];
handler?.Invoke(eventArgs);
// -------- THIS GETS PRINTED ------------
Debug.WriteLine("Got data from " + _hostname + ":" + register.Register + "(" + register.FriendlyName + ") : " + val[0]);
}
catch (Exception err)
{
Debug.WriteLine(err.ToString());
}
}
这个类的几个实例是在另一个类中创建的:
new Thread(() =>
{
tasks.Add(Task.Factory.StartNew(() =>
{
_masters.Add(new HMIMaster().Connect(ipAddress, port).SetRegisters(registers));
_masters.Last().OnEvent += HMIEvent;
Debug.WriteLine(_masters.Count + " masters");
}));
}).Start();
private static void HMIEvent(HMIEventArgs e)
{
// HOWEVER THIS SOMETIMES DOESN'T SHOW FOR
// ALL INSTANCES OF THE PREVIOUS CLASS
Debug.WriteLine(">> in logger (" + e.IPAddress + " " + e.Event + ") >> " + e.Name + " :: " + e.Data);
var handler = OnEvent;
handler?.Invoke(e);
}
我在这里做错了吗?
我会使用静态事件来避免每次在新实例上注册并在处置时取消注册(以避免内存泄漏)。 在您的情况下不需要锁定,所以我会像这样简化它:
(一级)
public static event EventHandler<HMIEventArgs> HMIEvent;
private void OnHMIEvent(HMIEventArgs e)
{
HMIEvent?.Invoke(this, e);
}
private void ReadReg(RegisterMap register)
{
...
OnHMIEvent(new HMIEventArgs()
{
Name = register.FriendlyName,
Event = Events.GotData,
IPAddress = _hostname,
eventArgs.Data = val[0]
});
...
}
(二等)
...
FirstClass.HMIEvent += FirstClass_HMIEvent; // Probably in your static constructor, register only once (unregister if required on disposal)
...
private void FirstClass_HMIEvent(object sender, HMIEventArgs e)
{
// (FirstClass)sender can be used here if required
}
顺便说一句,您的示例代码中的这两行不应该存在(在您的静态 HMIEvent 方法中,您没有向我们提供第二类的 OnEvent 是什么,并且您不需要每次都将它传递给处理程序 var):
var handler = OnEvent;
handler?.Invoke(e);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.