blocked in IConnectionPoint::Advise

Lowell Liu 106 Reputation points
2025-11-26T05:53:22.2+00:00

When I use this api named IConnectionPoint::Advise in my app main thread, the whole app frozen, only happened once. Why and how to fix it?
here is the stack:

00 00000082`9673a5f8 00007ffd`a32b61c4     : 00000456`975ae87d 00000082`9673ab60 00000082`9673ab60 00000000`00000000 : win32u!NtUserMsgWaitForMultipleObjectsEx+0x14
01 00000082`9673a600 00007ffd`a32b5e81     : 0000027b`7ac30e80 00000082`9673ab60 0000027b`6246321b 00000000`00000000 : combase!CCliModalLoop::BlockFn+0x110 [onecore\com\combase\dcomrem\callctrl.cxx @ 2115] 
02 00000082`9673a690 00007ffd`a32c1196     : 00000000`ffffffff 0000027b`00000000 0000027b`7ac30e80 00000082`9673a760 : combase!ModalLoop+0xb9 [onecore\com\combase\dcomrem\chancont.cxx @ 171] 
03 (Inline Function) --------`--------     : --------`-------- --------`-------- --------`-------- --------`-------- : combase!ThreadSendReceive+0x1316 (Inline Function @ 00007ffd`a32c1196) [onecore\com\combase\dcomrem\channelb.cxx @ 7309] 
04 (Inline Function) --------`--------     : --------`-------- --------`-------- --------`-------- --------`-------- : combase!CSyncClientCall::SwitchAptAndDispatchCall+0x13af (Inline Function @ 00007ffd`a32c1196) [onecore\com\combase\dcomrem\channelb.cxx @ 5785] 
05 00000082`9673a700 00007ffd`a32b4fe2     : 0000027b`75595d20 0000027b`7aa8b300 00000000`00000000 0000027b`75595d20 : combase!CSyncClientCall::SendReceive2+0x1596 [onecore\com\combase\dcomrem\channelb.cxx @ 5347] 
06 (Inline Function) --------`--------     : --------`-------- --------`-------- --------`-------- --------`-------- : combase!SyncClientCallRetryContext::SendReceiveWithRetry+0x37 (Inline Function @ 00007ffd`a32b4fe2) [onecore\com\combase\dcomrem\callctrl.cxx @ 1503] 
07 (Inline Function) --------`--------     : --------`-------- --------`-------- --------`-------- --------`-------- : combase!CSyncClientCall::SendReceiveInRetryContext+0x37 (Inline Function @ 00007ffd`a32b4fe2) [onecore\com\combase\dcomrem\callctrl.cxx @ 581] 
08 00000082`9673ab40 00007ffd`a32b375a     : 00000082`9673ad60 00000000`00000000 0000027b`75595d20 00000082`9673ad00 : combase!ClassicSTAThreadSendReceive+0x1a2 [onecore\com\combase\dcomrem\callctrl.cxx @ 563] 
09 00000082`9673ac60 00007ffd`a32df593     : 00007ffd`a3520df8 00007ffd`a32de3a7 00000000`00000000 0000027b`7aafc318 : combase!CSyncClientCall::SendReceive+0x55a [onecore\com\combase\dcomrem\ctxchnl.cxx @ 797] 
0a (Inline Function) --------`--------     : --------`-------- --------`-------- --------`-------- --------`-------- : combase!CClientChannel::SendReceive+0x49 (Inline Function @ 00007ffd`a32df593) [onecore\com\combase\dcomrem\ctxchnl.cxx @ 674] 
0b 00000082`9673add0 00007ffd`a2167a91     : 00000000`00000000 00000082`00000000 0000027b`7ac292f0 00007ffd`a34e7880 : combase!NdrExtpProxySendReceive+0xb3 [onecore\com\combase\ndr\ndrole\proxy.cxx @ 1899] 
0c 00000082`9673ae20 00007ffd`a32dd486     : 00007ffd`a34fcef0 00000000`00000000 0000027b`73141800 0000027b`731402fc : RPCRT4!NdrpClientCall3+0x431
0d 00000082`9673b190 00007ffd`a34a74b2     : 00007ffd`97c5cec0 00000082`9673b640 0000027b`00002710 00000082`9673b659 : combase!ObjectStublessClient+0x146 [onecore\com\combase\ndr\ndrole\amd64\stblsclt.cxx @ 366] 
0e 00000082`9673b520 00007ffd`97c7c79e     : 0000027b`7aafc318 0000027b`7aa8b300 0000027b`7aa8b588 00000456`96e0b026 : combase!ObjectStubless+0x42 [onecore\com\combase\ndr\ndrole\amd64\stubless.asm @ 176] 
0f 00000082`9673b570 00007ffd`97c59100     : 00000082`9673b640 00000000`00000004 00000000`00000000 0000027b`7aa8b300 : netprofm!std::_Func_impl_no_alloc<`PublicNetworkListManager::PrivateNetworkEventSync::AdviseNotifyNetworkInterfaceEvents'::`11'::<lambda_1>,void>::_Do_call+0x2e
10 00000082`9673b5b0 00007ffd`97c7ab66     : 00000000`00000000 0000027b`7aa8b2f0 0000027b`7aa8b2f0 00000045`00000000 : netprofm!TraceOnRpcTimeout+0x4c
11 00000082`9673b620 00007ffd`97c6a7e3     : 00000000`00000000 00000000`00000000 0000027b`75ce7d20 0000027b`75ce7ea8 : netprofm!PublicNetworkListManager::PrivateNetworkEventSync::AdviseNotifyNetworkInterfaceEvents+0xee
12 00000082`9673b6c0 00007ffd`97c7031d     : 00000000`00000000 00000082`9673b859 0000027b`75ce7d40 00000000`00000006 : netprofm!PublicNetworkListManager::EnsureAdvises+0xf3
13 00000082`9673b710 00007ffc`e0e0dba9     : 0000027b`75ae0c90 0000027b`755accb0 37313437`3431322d 0000027b`755acca0 : netprofm!PublicNetworkListManager::NetworkConnectionEventsAdvise+0xed
Developer technologies | C++
Developer technologies | C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
0 comments No comments
{count} votes

Answer accepted by question author
  1. RLWA32 51,361 Reputation points
    2025-12-01T12:51:35.97+00:00

    I put together a sample Win32 application that demonstrates using the MTA to handle NetworkListManagerEvents and NetworkConnectionEvents. It contains solution/project created with VS2022. As a sample, it has minimal error checking.

    You can download the zip file containing the sample from https://1drv.ms/u/c/c389bf4121acea69/IQDCt_pYXf6CQ7OHb_SBJ_mJAYeByYfwHb2rnTlQYkVex9I?e=UMlapP

    Don't forget to unblock the zip file before you extract the contents.


Answer accepted by question author
  1. Omkara Varshitha Kunapalli (INFOSYS LIMITED) 1,985 Reputation points Microsoft External Staff
    2025-11-26T06:52:59.0633333+00:00

    Hello hope your doing well

    Step-by-step procedure to fix or avoid the freeze

    1. Confirm apartment model
      • Make sure the thread calling Advise is initialized with STA:
      HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
      Don’t call Advise before COM is initialized Avoid running Advise on the UI thread
    • Best practice: move Advise off the main thread to a dedicated STA worker with its own message loop. This keeps your UI responsive if COM blocks

    // Create a dedicated STA thread std::thread staThread([&] {     CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);     // optional: CoInitializeSecurity(...) early     // Perform Advise here     // cp->Advise(pSink, &cookie);

    • // Message loop to satisfy COM re-entrancy     MSG msg;     while (GetMessage(&msg, nullptr, 0, 0)) {         TranslateMessage(&msg);         DispatchMessage(&msg);     }     CoUninitialize(); }); staThread.detach();

    Ensure a message pump is present if you must use STA

    • STA requires a message loop for COM re-entrancy. If you call Advise in an STA with no pump, COM can deadlock. Keep the pump running or perform Advise from that STA worker thread.
    • Do not hold locks or call Advise from inside callbacks
      • Release locks and avoid calling Advise from window procedures, COM callbacks, or any code that depends on the UI thread being responsive. Re-entrancy plus held locks is a common deadlock cause.
      Validate the event interface and sink
      • Use the correct IID from IConnectionPoint::GetConnectionInterface and ensure your sink supports the expected interface (IDispatch vs. vtable). Mis-matched interfaces can fail or stall negotiations.
      • If your sink lives on a different thread, marshal it properly (e.g., IGlobalInterfaceTable or CoMarshalInterThreadInterfaceInStream) before calling Advise.
      • Initialize COM security early
        • Call CoInitializeSecurity once early in process startup (before any COM calls) with settings appropriate for callbacks. Mismatched security can cause delays or failures on callback setup.
        Add resilience: timeouts and async workflow
        • Wrap Advise in an async operation on the STA worker and detect hangs (e.g., if it takes >5 seconds, log and continue UI).
        • Consider retrying later or during idle time if the server is busy.
        • Unadvise cleanly on shutdown
          • Keep the DWORD cookie and call Unadvise from the same apartment you used for Advise. Ensure the sink’s lifetime covers the subscription

     


1 additional answer

Sort by: Most helpful
  1. Q&A Assist
    2025-11-26T05:53:30.4033333+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    When using the IConnectionPoint::Advise method, if your application freezes, it could be due to blocking calls or deadlocks occurring in the main thread. The stack trace you provided indicates that the application is waiting for a message or event, which can happen if the thread is blocked by a long-running operation or if it is waiting for a response from another thread that is also blocked.

    To address this issue, consider the following approaches:

    1. Use a Separate Thread: Avoid calling IConnectionPoint::Advise on the main UI thread. Instead, perform this operation on a worker thread to prevent the UI from freezing.
    2. Check for Deadlocks: Review your code to ensure that there are no potential deadlocks when multiple threads are waiting for each other to release resources.
    3. Timeouts: Implement timeouts for operations that might block for an extended period. This can help prevent the application from becoming unresponsive.
    4. Debugging: Use debugging tools to analyze the state of threads and identify where the blockage occurs. This can provide insights into what is causing the freeze.
    5. Event Handling: Ensure that your event handling logic is efficient and does not perform long-running tasks on the thread that processes events.

    By implementing these strategies, you should be able to mitigate the freezing issue when using IConnectionPoint::Advise.


    References:

    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.