Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>My answer is very similar to @EricBrown's one, but there is one different point. </p> <p>Creating a <a href="http://blogs.msdn.com/b/nickkramer/archive/2006/05/06/591252.aspx" rel="nofollow noreferrer">nested message loop</a> with <code>MsgWaitForMultipleObjectsEx</code> may lead to code reentrancy on the same thread (via a window message dispatched by the inner <code>PeekMessage/TranslateMessage/DispatchMessage</code> pattern). At worst scenario, you may end up calling the same COM object method <em>before</em> the previous call has returned. </p> <p>I would first try using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680732%28v=vs.85%29.aspx" rel="nofollow noreferrer">CoWaitForMultipleHandles</a> with <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms693767%28v=vs.85%29.aspx" rel="nofollow noreferrer">COWAIT_DISPATCH_CALLS</a> (but without <code>COWAIT_DISPATCH_WINDOW_MESSAGES</code>). In case your COM object is provided by an out-of-proc server, this most likely should work. Otherwise, you should consider putting some reentrancy checks in place.</p> <p>I have a <a href="https://stackoverflow.com/questions/18050438/handling-ckeditor-async-calls-synchronously-with-c-sharp-winforms-webbrowser-con">related question</a> with some code showing how it could be done with C# (I had to use <code>COWAIT_DISPATCH_WINDOW_MESSAGES</code> there, otherwise the event I was after wasn't getting fired). </p> <p><strong>[UPDATE]</strong> Ideally, you should use <code>async/await</code> pattern for things like that and wrap your event as a task (e.g. <a href="https://stackoverflow.com/a/18317508/1768303">here's how</a>). I understand, sometimes it is not feasible to re-factor existing code to use this approach. However, if a pending operation takes considerable time to complete, a more user-friendly way to wait for its completion event might be just to show a modal dialog with a nice "please wait..." message (as discussed here in <a href="https://stackoverflow.com/a/18317508/1768303">comments</a>). You'd just close this dialog from your event handler. In fact, AFAIK, this is the only endorsed way for a WinForms app to enter a nested message loop. </p> <p><strong>[UPDATE]</strong> As Eric pointed out in comments, <code>COWAIT_DISPATCH_WINDOW_MESSAGES</code> is indeeded required for an STA thread. Apparently, <code>COWAIT_DISPATCH_CALLS</code> is intended for the new little-known <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh750290.aspx" rel="nofollow noreferrer">ASTA model</a> and <em><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms693767%28v=vs.85%29.aspx" rel="nofollow noreferrer">has no meaning in other apartment types</a></em>. </p> <p>In case with out-of-proc COM servers, .NET event handlers are called back as free-threaded objects regardless of the waiting thread's apartment model (<a href="https://stackoverflow.com/q/18458398/1768303">in my experience</a>, it's never the same STA thread on which the out-of-proc object was originally created). Thus, waiting with <a href="http://msdn.microsoft.com/en-us/library/58195swd.aspx" rel="nofollow noreferrer">WaitHandle.WaitOne</a> (no pumping) should be sufficient. However, if the event handler accesses any state data besides the <code>WaitHandle</code>, proper synchronization is required (with <a href="http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx" rel="nofollow noreferrer">locks</a> etc).</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. 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.
 

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