繁体   English   中英

c#通过反射从BackgroundWorker.DoWork删除所有事件处理程序

[英]c# remove all event handler from BackgroundWorker.DoWork by Reflection

此链接为我提供了帮助- 如何从控件中删除所有事件处理程序

是的,我成功从控件和窗体中删除了所有事件处理程序。

但是我在BackgroundWorker中失败了。

这是我的代码。

    void ReadingCompleted()
    {
        //find fields
        List<FieldInfo> liField=typeof(BackgroundWorker).GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Public).ToList();

        foreach(FieldInfo field in liField)
        {
            txtbox_log.Text += field.Name + "\r\n";
        }
        //below output list 
        //canCancelWorker
        //workerReportsProgress
        //cancellationPending
        //isRunning
        //asyncOperation
        //threadStart
        //operationCompleted
        //progressReporter
        //doWorkKey
        //runWorkerCompletedKey
        //progressChangedKey

        //remove all eventhandler
        object key = typeof(BackgroundWorker).GetField("doWorkKey", BindingFlags.NonPublic | BindingFlags.Static);

        EventHandlerList events = (EventHandlerList)typeof(Component)
        .GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance)
        .GetValue(this, null);
        events.RemoveHandler(key, events[key]);
        waitForm.Close();
    }

强烈建议不要编写这样的代码。 一个经过精心设计的实现应该不需要任意删除预订给任何类的任何事件的所有处理程序,包括DoWorkBackgroundWorker其他事件。 唯一应该删除处理程序的代码是添加该处理程序的相同代码,并且该代码知道它添加了哪个处理程序,因此可以直接将其删除。

就是说,假设您发布的代码是在继承BackgroundWorker类的类中找到的,那么它对您不起作用的唯一原因是您正尝试使用从GetField("doWorkKey", ...)获取的FieldInfo对象GetField("doWorkKey", ...)调用作为事件处理程序的实际键,实际上,您应该调用该对象的GetValue()方法来获取实际键值。

正确的代码如下所示:

FieldInfo keyField = typeof(BackgroundWorker)
    .GetField("doWorkKey", BindingFlags.NonPublic | BindingFlags.Static);
object key = keyField.GetValue(bw);

如果您发布的代码不在继承BackgroundWorker类的类中(或者即使继承但不是您要修改的BackgroundWorker对象),那么您将遇到第二个问题。 在此处调用GetValue()方法时,还需要提供正确的BackgroundWorker实例:

EventHandlerList events = (EventHandlerList)typeof(Component)
    .GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(this, null);

也就是说,强似thisGetValue()方法,你就需要通过参考实际BackgroundWorker你要修改的对象。

暂无
暂无

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

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