Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Try this code</p> <pre><code> Form1 form1 = new Form1(); //Subscribe event here form1.MdiParent = this; form1.Show(); </code></pre> <p>This works for me</p> <p><strike>I don't know why your code doesn't work, I'll get back once I get the answer.</strike></p> <p>Edit: I have got the answer now.</p> <p><code>ISynchronizationInvoke's</code> members (<code>Invoke</code> and <code>BeginInvoke</code>) are implemented by <code>Control</code> class as follows.</p> <ol> <li>Gets context of Thread which created the window.</li> <li>Generate a new window messageId using <code>RegisterWindowMessage</code></li> <li>Encapsulate the delegate we passed as a parameter in <code>ThreadMethodEntry</code> add it into control's internal <code>Queue</code></li> <li>Posts the message to thread's queue with messageId returned by <code>RegisterWindowMessage</code> using <code>PostMessage</code></li> <li>Handles <code>WndProc</code> listens for <code>messageId</code> then De-queues the <code>ThreadMethodEntry</code> and invokes the delegate.</li> </ol> <blockquote> <p>What goes wrong here?</p> </blockquote> <p>Form1 form1 = new Form1(); form1.Show(); form1.MdiParent = this;</p> <p><code>Form.Show</code> somehow results in a call to <code>OnLoad</code> method, that is where <code>OnShown</code> is called Asynchronously using <code>BeginInvoke</code></p> <pre><code>if (base.IsHandleCreated) { base.BeginInvoke(new MethodInvoker(this.CallShownEvent));//reflected code } </code></pre> <p>So before the posted <code>WindowMessage</code> receives you set <code>form1.MdiParent = this;</code> which in turn forces the control to <code>Destroy</code> it's handle and <code>ReCreate</code> new handle.</p> <p><code>DestroyHandle</code> method swallows the posted message by getting it using <code>PeekMessage</code> function, and then enumerates all elements in <code>Queue</code> and sets its state as completed without invoking the delegate but marking it to throw <code>ObjectDisposedException</code>.</p> <pre><code>Form1 form1 = new Form1(); form1.Show(); Action del = () =&gt; { Console.WriteLine("This will never be called");//our custom delegates too fails to be invoked }; var res = form1.BeginInvoke(del); //after some more code form1.EndInvoke(res);//throws `ObjectDisposedException` which was marked previously form1.MdiParent = this; </code></pre> <p>throwing <code>ObjectDisposedException("Control")</code> is actually misleading isn't it?</p> <p>Note: You can fix this easily using <code>Application.DoEvents();</code> before <code>form1.MdiParent = this;</code> since <code>DoEvents</code> process all the pending messages immediately.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload