1

i am helped by this link -How to remove all event handlers from a control

yep i succeed remove all event handler from control and form.

but i have failed in BackgroundWorker.

this is my code.

    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();
    }
santutu
  • 119
  • 1
  • 9

1 Answers1

0

I strongly recommend against writing code like this. A well-designed implementation should have no need to arbitrarily remove all handlers subscribed to any event of any class, including the DoWork or other event of BackgroundWorker. The only code that ought to be removing a handler is the same code that added the handler, and that code knows what handler it added and so can remove it directly.

That said, assuming the code you posted is found in a class that inherits the BackgroundWorker class, the only reason it doesn't work for you is that you are trying to use the FieldInfo object you get back from the GetField("doWorkKey", ...) call as the actual key for the event handler, which in fact you should be calling that object's GetValue() method to get the actual key value.

The correct code would look like this:

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

If the code you posted is not in a class that inherits the BackgroundWorker class (or, even if it is but it's not the BackgroundWorker object you are trying to modify), then you have a second problem. You also need to provide the correct BackgroundWorker instance when calling the GetValue() method here:

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

That is, instead of passing this to the GetValue() method, you would need to pass the reference to the actual BackgroundWorker object you're trying to modify.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136