繁体   English   中英

在 c# 中使用反射添加和删除异步事件处理程序

[英]Add and remove async event handlers using reflection in c#

我有以下实际有效的代码示例:

namespace DeviceLib
{
    public interface IInstrument
    {
        event Action<InstrumentConnectionStatus> OnConnectionChanged;
        event Action OnRemoteMeasureRequested;
    }

public class InstrumentInstance
{
    public delegate Task EventCompletedHandler(object sender, dynamic eventArgs);
    public event EventCompletedHandler StatusChanged = async delegate { };
    public event EventCompletedHandler RemoteMeasureRequested = async delegate { };
    IInstrument Instrument;

    public InstrumentInstance(string DriverName)
    {
        Instrument = DriverName switch
        {
            Instrument1.DRIVER => new Instrument1Driver(),
            instrument2.DRIVER => new Instrument2Driver(),
            _ => throw new NotSupportedException($"Driver {DriverName} not supported"),
        };
    }

    public async Task<object> OnStatusChanged()
    {
        Instrument.OnConnectionChanged += async (InstrumentConnectionStatus status) =>
        {
            await StatusChanged(nameof(OnStatusChanged), status.ToString());
        };

        return null;
    }

    public async Task<object> OnRemoteMeasureRequested()
    {
        Instrument.OnRemoteMeasureRequested += async () =>
        {
            await RemoteMeasureRequested(nameof(OnRemoteMeasureRequested), null);
        };

        return null;
    }
}

}

namespace DeviceConsumer 
{
    public class InstrumentService
    {
        static Type Type = typeof(DeviceLib.InstrumentInstance);
        DeviceLib.InstrumentInstance InstrumentInstance;
        static List<MethodInfo> AvailableEventHandlers =  Type.GetMethods().Where(x => x.DeclaringType == Type && !x.IsSpecialName && x.Name.StartsWith("On")).ToList();
        static List<EventInfo> AvailableEvents=Type.GetEvents().ToList();
    

        public InstrumentService()
        {

        }

        public async Task CreateInstrumentInstance(string driverName)
        {
            this.InstrumentInstance = new DeviceLib.InstrumentInstance(driverName);
        
        
            // Invoking the methods that wrap the event handlers with reflection
            foreach (MethodInfo eventHandler in AvailableEventHandlers)
                await (Task<object>)eventHandler.Invoke(InstrumentInstance, new object[] { });


            InstrumentInstance.StatusChanged +=  async(s,e) => await ProcessInstrumentEvent(s,e);
            InstrumentInstance.RemoteMeasureRequested += async (s, e) => await ProcessInstrumentEvent(s, e);
        }

        private async Task ProcessInstrumentEvent(object sender, dynamic eventArgs)
        {
            await Task.Run(() =>
            {
                Console.Write($"Event {sender} Fired!");
            });
        }

}

 

现在我想替换将事件关联到 ProcessInstrumentEvent 方法的 static 部分:

InstrumentInstance.StatusChanged +=  async(s,e) => await ProcessInstrumentEvent(s,e);
InstrumentInstance.RemoteMeasureRequested += async (s, e) => await ProcessInstrumentEvent(s, e);

有类似的东西:

        foreach (EventInfo ev in AvailableEvents)
        {
           // EventHandler handler = async delegate (object s, dynamic e) { await ProcessInstrumentEvent(s, e); };
          
           //  EventHandler handler = new EventHandler(async (s, e) => await ProcessInstrumentEvent(s,e));


             ev.AddEventHandler(InstrumentInstance, handler);

        }

定义“处理程序”的两种方法都不起作用,我在这里失败了吗? 我认为我非常接近,此实现的目标是动态添加(然后删除)针对 class“InstrumentService”中的方法“ProcessInstrumentEvent”的处理程序,因此不使用 += 和 -= 运算符,所以我认为我可以使用反射方法“AddEventHandler”和“RemoveEventHandler”来实现

这应该有效:

var obj = new InstrumentInstance("foo");

EventCompletedHandler handler = async (s, e) => await ProcessInstrumentEvent(s, e);

foreach (var evt in obj.GetType().GetEvents(BindingFlags.Public | BindingFlags.Instance))
{
    if (evt.EventHandlerType == typeof(EventCompletedHandler))
    {
        Console.WriteLine($"Binding '{evt.Name}'");
        evt.AddEventHandler(obj, handler);
    }
}

它也应该在没有额外间接的情况下工作:

EventCompletedHandler handler = ProcessInstrumentEvent;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM