如何手动调用事件? [英] How to manually invoke an event?
问题描述
我在C#中有以下行:
_timer.ElapsedTick += _somefunction1;
_timer.ElapsedTick += _somefunction2;
_timer.ElapsedTick += _somefunction3;
如何调用订阅_timer.ElapsedTick的所有方法,而不指定_some函数?在这个伪线的某处
How to invoke all methods subscribed to _timer.ElapsedTick without specifying the _somefunction ? Somewhere along this pseudo-line
invoke(_timer.ElapsedTick);
您的帮助非常感谢。
更新
来自@ M.Babcock的示例正在工作。 FireEvent方法有魔法。谢谢。
Example from @M.Babcock is working. The FireEvent method does the magic. Thank you.
class InvokeFromMe
{
public event EventHandler RaiseMe;
}
class MainClass
{
public MainClass()
{
InvokeFromMe fromMe = new InvokeFromMe();
fromMe.RaiseMe += fromMe_RaiseMe;
fromMe.RaiseMe += fromMe_RaiseMe1;
FireEvent(fromMe, "RaiseMe", null, EventArgs.Empty);
//works
System.Timers.Timer _timer = new System.Timers.Timer();
_timer.Elapsed += _timer_Elapsed;
FireEvent(_timer, "onIntervalElapsed", null, null);
//throws exception
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("_timer_Elapsed raised");
}
private void fromMe_RaiseMe(object sender, EventArgs e)
{
Console.WriteLine("Event Handler 0 Raised");
}
private void fromMe_RaiseMe1(object sender, EventArgs e)
{
Console.WriteLine("Event Handler 1 Raised");
}
public void FireEvent(object onMe, string invokeMe, params object[] eventParams)
{
MulticastDelegate eventDelagate =
(MulticastDelegate)onMe.GetType().GetField(invokeMe,
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic).GetValue(onMe);
Delegate[] delegates = eventDelagate.GetInvocationList();
foreach (Delegate dlg in delegates)
{
dlg.Method.Invoke(dlg.Target, eventParams);
}
}
}
class Program
{
static void Main(string[] args)
{
MainClass m = new MainClass();
}
}
推荐答案
可以它使用传统的C#?否(如前所述)。但是使用反射是有可能的。这是基于这个MSDN论坛主题:
Can it be done using conventional C#? No (as previously stated). But using reflection it is possible. Here is some tested code based on the answer to this MSDN forum thread:
class InvokeFromMe
{
public event EventHandler RaiseMe;
}
class Program
{
static void Main(string[] args)
{
var fromMe = new InvokeFromMe();
fromMe.RaiseMe += fromMe_RaiseMe;
fromMe.RaiseMe += fromMe_RaiseMe1;
fromMe.RaiseMe += fromMe_RaiseMe2;
FireEvent(fromMe, "RaiseMe", null, EventArgs.Empty);
}
static void fromMe_RaiseMe(object sender, EventArgs e)
{
Console.WriteLine("Event Handler 0 Raised");
}
static void fromMe_RaiseMe1(object sender, EventArgs e)
{
Console.WriteLine("Event Handler 1 Raised");
}
static void fromMe_RaiseMe2(object sender, EventArgs e)
{
Console.WriteLine("Event Handler 2 Raised");
}
public static void FireEvent(object onMe, string invokeMe, params object[] eventParams)
{
MulticastDelegate eventDelagate =
(MulticastDelegate)onMe.GetType().GetField(invokeMe,
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic).GetValue(onMe);
Delegate[] delegates = eventDelagate.GetInvocationList();
foreach (Delegate dlg in delegates)
{
dlg.Method.Invoke(dlg.Target, eventParams);
}
}
}
更新
我不熟悉 System.Timer.Timer
类,所以我我不知道与我提供的例子有什么不同。您可以尝试以下方式:
I'm not familiar with the System.Timer.Timer
class, so I'm not sure what is different from my provided example. You could perhaps try something like:
public static void FirePublicEvent(object onMe, string invokeMe, params object[] eventParams)
{
MulticastDelegate eventDelagate =
(MulticastDelegate)onMe.GetType().GetField(invokeMe,
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public).GetValue(onMe);
Delegate[] delegates = eventDelagate.GetInvocationList();
foreach (Delegate dlg in delegates)
{
dlg.Method.Invoke(dlg.Target, eventParams);
}
}
这篇关于如何手动调用事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!