0

I'm trying to fill a knowledge gap. I have a control that calls BeginInvoke(delegate), then afterward the control immediately disposes itself.

The delegate never seems to occur. It would seem to be a result of the Control.Dispose().

My confusion lies in the fact that (I thought) BeginInvoke places the delegate onto the Windows Message Queue to be processed later on the UI thread. Why would disposing the control have anything to do with this delegate no longer firing? It was already placed on the queue before disposing.

Also, if it has something to do with the Windows Handle, why do I not get an Exception instead of a quiet ignore of the delegate?

below is a simple example of what I mean:

class myControl : UserControl
{
    public myControl()
        : base()
    { }

    public void DoBeginInvoke()
    {
        this.BeginInvoke(new MethodInvoker(
            () => { Console.WriteLine("!!TESTING 123!!"); }
        ));

         // silently prevents the delegate from occuring..
        this.Dispose();
    }
}

Thanks in advance for your explanation. Apologies for the simplistic question.

n00bCoder
  • 3
  • 1
  • Are you sure that the object isn't disposed prior to the method being invoked? The Dispose call should be executed immediately, while the BeginInvoke is queued for later. – Ron Beyer Nov 23 '15 at 20:56
  • This is quite intentional, Control.Dispose() goes through the invoke queue and removes any pending invokes. Not doing so would make it a lot more likely that your program bombs with an ObjectDisposedException in a very hard to diagnose way. It is just a band-aid, not a real fix, it makes your bug easier to diagnose. Having a thread continue to invoke after the UI is gone is a very common bug. – Hans Passant Nov 24 '15 at 01:17
  • Thank you Hans Passant. That explanation added valuable extra insight for me. – n00bCoder Nov 24 '15 at 01:54

1 Answers1

2

As far as I know, BeginInvoke is implemented as a PostMessage, and Dispose will call DestroyWindow on Window Handle Check this answer and the linked MSDN page about DestroyWindow: it say it

flushes the thread message queue.

So it means your BeginInvoke will be flushed as well

Community
  • 1
  • 1
Gian Paolo
  • 4,161
  • 4
  • 16
  • 34
  • Thank you; this is exactly what I needed to hear. Flushing of the message queue on dispose was apparently the gap I didn't understand. – n00bCoder Nov 24 '15 at 01:52