Документация MSDN для метода CCmdTarget :: OnFinalRelease довольно коротка:
Вызывается платформой при выпуске последней ссылки OLE на объект или с него.
Я создал подкласс CCmdTarget
class CMyEventHandler : public CCmdTarget { ... }
Я пытаюсь выяснить, при каких условиях будет вызываться метод OnFinalRelease.У меня есть код, который выглядит примерно так:
CMyEventHandler* myEventHandler = new CMyEventHandler();
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(FALSE);
AfxConnectionAdvise(myEventSource, DIID_IMyEventInterface, pUnk, FALSE, myCookie);
// Application continues...events arrive...eventually the event sink is shutdown
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(FALSE);
AfxConnectionUnadvise(myEventSource, DIID_IMyEventInterface, pUnk, FALSE, myCookie);
Используя этот код, я замечаю, что метод OnFinalRelease никогда не вызывается.Это означает, что у меня утечка памяти.Поэтому я изменил заключительный код следующим образом:
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(FALSE);
AfxConnectionUnadvise(myEventSource, DIID_IMyEventInterface, pUnk, FALSE, myCookie);
delete myEventHandler;
myEventHandler = NULL;
Этот раздел кода запускается периодически в течение дня.Теперь я заметил, что, хотя деструктор для упакованного экземпляра myEventHandler вызывается, как и ожидалось, функция OnFinalRelease теперь вызывается!Что еще хуже, он вызывается не для экземпляра, который был упакован, а для только что созданного экземпляра CMyEventHandler!Думая, что это может быть связано с проблемой подсчета ссылок, я изменил свой код подключения и обработки:
CMyEventHandler* myEventHandler = new CMyEventHandler();
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(TRUE);
AfxConnectionAdvise(myEventSource, DIID_IMyEventInterface, pUnk, TRUE, myCookie);
pUnk->Release();
// Application continues...events arrive...eventually the event sink is shutdown
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(TRUE);
AfxConnectionUnadvise(myEventSource, DIID_IMyEventInterface, pUnk, TRUE, myCookie);
pUnk->Release();
delete myEventHandler;
myEventHandler = NULL;
Я позволил этому запускаться весь день и теперь наблюдаю, что OnFinalRelease никогда не вызывается.Деструктор для обернутого экземпляра вызывается так, как я и ожидал, но я чувствую себя неловко, поскольку я явно не понимаю обстоятельств, при которых вызывается OnFinalRelease.OnFinalRelease вызывается с некоторой задержкой, или есть способ заставить его срабатывать?Что вызовет вызов OnFinalRelease?
Если это имеет значение, источником события является сборка .NET, представляющая события через взаимодействие COM.