单事件订阅我相信这是不可能的,但我会问。对于事件的单个订阅,我经常发现自己使用这种(自己发明的)模式:EventHandlerhandler=null;handler=(sender,e)=>{SomeEvent-=handler;初始化();};SomeEvent+=处理程序;这是一个相当大的样板文件,它也让Resharper抱怨修改后的上限。有没有办法将此模式转换为扩展方法或类似方法?这样做的更好方法是什么?理想情况下,我想要这样的东西:SomeEvent.OneShot(handler)重构扩展方法并不容易,因为在C#中引用事件的唯一方法是订阅(+=)或取消订阅(-=)(除非它在当前类中声明)。您可以使用与ReactiveExtensions中相同的方法:Observable.FromEvent需要两个委托来订阅事件和取消订阅。所以你可以这样做:actualHandler=(sender,e)=>{unsubscribe(actualHandler);处理程序(发件人,e);};订阅(实际处理程序);}}...Foof=newFoo();EventHelper.SubscribeOneShot(handler=>f.Bar+=handler,handler=>f.Bar-=handler,(sender,e)=>{/*whatever*/});以下代码对我有用。必须通过字符串指定事件并不完美,但我不知道如何解决这个问题。我想这在当前的C#版本中是不可能的。使用系统;使用System.Reflection;namespaceTestProject{publicdelegatevoidMyEventHandler(objectsender,EventArgse);公共类MyClass{公共事件MyEventHandlerMyEvent;publicvoidTriggerMyEvent(){if(MyEvent!=null){MyEvent(null);}else{Console.WriteLine("没有注册事件处理器。");}}}publicstaticclassMyExt{publicstaticvoidOneShot(thisTAinstance,stringeventName,MyEventHandlerhandler){EventInfoi=typeof(TA).GetEvent(eventName);我的事件处理程序newHandler=null;newHandler=(sender,e)=>{handler(sender,e);i.RemoveEventHandler(实例,newHandler);};i.AddEventHandler(实例,newHandler);}}publicclassProgram{staticvoidMain(string[]args){MyClassc=newMyClass();c.OneShot("MyEvent",(sender,e)=>Console.WriteLine("Handlerexecuted."));c.TriggerMyEvent();c.TriggerMyEvent();我建议使用“自定义”事件,以便您可以访问呼叫列表,然后使用Interlocked.Exchange同时读取和清除呼叫列表以引发事件。如果需要,可以使用简单的链表以线程安全的方式完成事件订阅/取消订阅/提升;引发事件时,代码可以反转Interlocked.Exchange之后堆栈项的顺序。对于取消订阅方法,我可能建议只在调用列表项中设置一个标志。如果在不引发事件的情况下重复订阅和取消订阅事件,理论上这可能会导致内存泄漏,但这将允许使用非常简单的线程安全取消订阅方法。如果要避免内存泄漏,可以统计列表中还有多少未订阅的事件;如果在尝试添加新事件时列表中有太多未订阅的事件,则add方法可以遍历列表并将其删除。在完全无锁的线程安全代码中仍然可用,但更复杂。以上就是《C#学习教程:单个事件订阅》分享的全部内容。如果对你有用,需要进一步了解《C#学习教程》,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
