Hello hope your doing well
Step-by-step procedure to fix or avoid the freeze
- 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