如何手动调用事件?

我在C#中有以下行:

_timer.ElapsedTick += _somefunction1; _timer.ElapsedTick += _somefunction2; _timer.ElapsedTick += _somefunction3; 

如何在不指定_somefunction的情况下调用订阅_timer.ElapsedTick的所有方法? 沿着这条伪线的某个地方

 invoke(_timer.ElapsedTick); 

非常感激您的帮忙。

更新

来自@ M.Babcock的例子正在运作。 FireEvent方法具有魔力。 谢谢。

 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#完成吗? 不( 如前所述 )。 但是使用reflection是可能的。 以下是基于此MSDN论坛post答案的一些经过测试的代码:

 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); } } } 

UPDATE

我不熟悉System.Timer.Timer类,所以我不确定与我提供的示例有什么不同。 您也许可以尝试以下方法:

 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); } } 

您不能调用由其他类型拥有的事件。 只能从声明它的类内部调用事件。

这是一个解决方法,你不能遍历Elapsed事件。 但要调用它们,让计时器完成工作。 System.Timer的此代码,不确定您使用的是哪个计时器。

假定计时器已启用:

 int interval = timer.Interval; ElapsedEventHandler handler = null; handler = (s,e) => { timer.Interval = interval; // put interval back to original value timer.Elapsed -= handler; }; timer.Elapsed += handler; timer.Interval = 1; // 1 millisecond, pretty much going to fire right now (as soon as you let it) 

这样的事情将触发事件,但您的原始间隔将重新启动。 如果你想保留原始的刻度模式,你可能需要在那里做一些数学运算。

您可以创建一个运行它们的函数:

 public void RunAllFuncs() { _somefunction1(); _somefunction2(); _somefunction3(); } 

我想你可能需要使用InvokeMember:

 public void GetMethod(string methodName){ var args = new Object[] { [INSERT ARGS IF NECESSARY--SET TO NULL OTHERWISE] }; try { var t = new [INSERT NAME OF CLASS THAT CONTAINS YOUR METHOD](); Type typeInfo = t.GetType(); var result = typeInfo.InvokeMember(methodName, BindingFlags.InvokeMethod, null, t, args); return result; } catch (Exception ex) { return ex; } } 

然后这样称呼它:

 _timer.ElapsedTick += GetMethod("[INSERT METHOD NAME AS STRING]"); 

一定要包括这个:

 using System.Reflection; 

祝好运!

基于M.Babcock的上述答案 ,通过一些轻微的reflection方法更新。

GetTypeInfoGetDeclaredField替换了GetFieldGetDeclaredField dlg.Methoddlg.GetMethodInfo

  using System.Reflection; ... public static void FireEvent(this object onMe, string invokeMe, params object[] eventParams) { TypeInfo typeInfo = onMe.GetType().GetTypeInfo(); FieldInfo fieldInfo = typeInfo.GetDeclaredField(invokeMe); MulticastDelegate eventDelagate = (MulticastDelegate)fieldInfo.GetValue(onMe); Delegate[] delegates = eventDelagate.GetInvocationList(); foreach (Delegate dlg in delegates) { dlg.GetMethodInfo().Invoke(dlg.Target, eventParams); } } 

好吧,我最终在这里搜索如何简单地启动事件,没有任何自定义args或任何东西。 我知道OP问题不同! 但我想分享,我希望它可以帮助别人。

不简化版本:

  var Handler = EventNameHere; if (Handler != null) { Handler(this, EventArgs.Empty); } 

简化版本:

  EventNameHere?.Invoke(this, EventArgs.Empty); 

根据ElapsedTick事件的签名,您可以通过在声明它的类中调用它来触发事件。 例如:

 ElapsedTick(this, new EventArgs()); 

您只能从声明它的类中调用事件。 如果你编写了计时器类,你会像这样调用它:

 this.ElapsedTick(this, eventArgs); 

在计时器类之外,您可以执行以下操作以获得类似的行为:

 delegate void delegateSample(object sender, EventArgs e); delegateSample d; d += new delegateSample(_somefunction1); d += new delegateSample(_somefunction2); d(this, EventArgs.Empty); 

delegateSample实际上应该是ElapsedTick事件的类型,而不是声明另一个委托类型。 我只是不知道那个代表的名字。 只需确保为每个函数添加ElapsedTick事件和您声明的委托变量,然后可以从Timer类之外的委托中调用它们。