[英]Data being lost when sent via a different thread over COM server - previously worked in VC6, now broken in VS2010
從VC6轉換到VS2010時,我遇到了很多小問題,但是解決這一問題時遇到了問題。 下面是將數據從我的類發送到COM服務器時使用的委托。
編輯2:添加了代碼以檢查varResult。
HRESULT Fire_Msg(BSTR Msg)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[1];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
pvars[0] = Msg;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
delete [] pvars;
// Changed to display what happens to varResult.
if (varResult.scode != S_OK)
{
// Do some error handling... (later)
return varResult.scode;
}
else
{
return varResult.scode;
}
}
編輯2:從工作或不工作,varResult返回S_OK。 沒有不同。
當我在此行中斷時,從主進程或線程發送時,數據看起來正確:
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
編輯:我有工作和不工作的圖片。 它實際上只是表明,從從threadex啟動的線程進行調用時,數據已在“ disp”中正確設置,並且在執行“ pDispatch-> Invoke”時沒有問題。
非工作: :結束編輯
在另一個應用程序中,我有以下代碼來回答調度的數據:
BEGIN_DISPATCH_MAP(CGenRTEvent, CCmdTarget)
//{{AFX_DISPATCH_MAP(CGenRTEvent)
DISP_FUNCTION(CGenRTEvent, "OnMsgStr", OnMsgStr, VT_EMPTY, VTS_BSTR)
DISP_FUNCTION(CGenRTEvent, "OnMsg", OnMsg, VT_EMPTY, VTS_BSTR)
DISP_FUNCTION(CGenRTEvent, "OnEndRun", OnEndRun, VT_EMPTY, "")
DISP_FUNCTION(CGenRTEvent, "OnProgress", OnProgress, VT_EMPTY, VTS_I4 VTS_BSTR)
DISP_FUNCTION(CGenRTEvent, "OnISocket", OnISocket, VT_EMPTY, VTS_BSTR)
// DISP_FUNCTION(CGenRTEvent, "OnMsg", OnMsg, VT_EMPTY, VTS_PVARIANT)
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
BEGIN_INTERFACE_MAP(CGenRTEvent, CCmdTarget)
INTERFACE_PART(CGenRTEvent, DIID__IGenRTEvents, Dispatch)
END_INTERFACE_MAP()
void CGenRTEvent::OnMsgStr(LPCTSTR strMsg)
{
m_pFrame->OnMsgStr(strMsg);
}
從主線程(在第一個應用程序內部)使用時,會正確引發OnMsgStr。 從其他線程完成時,永遠不會引發OnMsgStr。 這在VC6中一直運行良好,但是VS2010不喜歡它。
編輯:我的問題是,如何防止數據丟失? 我相當確定原因與從另一個線程調用此事件有關,但不知道如何解決。
任何建議或意見表示贊賞嗎?
提前致謝。
在Paulo Madeira的慷慨幫助下,我能夠通過搜索KB280512來解決此問題,這使我進入了由PJ Naughter編寫的名為GPSCom的項目。 鏈接在這里http://www.naughter.com/gpscom2.html 。 我下載了他的代碼,他提供了一個名為“ ATLCPImplMT.h”的免費軟件,可以未經修改就以任何形式使用。 根據他的示例,我將代碼修改如下:
HRESULT Fire_Msg(BSTR Msg)
{
CComCritSecLock<CComAutoCriticalSection> lock(m_CPMTCritSec);
ATL::CComVariant varResult;
int nConnections = m_Clients.GetSize();
int nConnectionIndex;
ATL::CComVariant* pvars = new ATL::CComVariant[1];
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
ATL::CComPtr<IDispatch> sp;
if (SUCCEEDED(GetInterfaceAt(nConnectionIndex, sp)))
{
VariantClear(&varResult);
pvars[0] = Msg;
DISPPARAMS disp = { pvars, NULL, 1, 0 };
sp->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
if (varResult.scode != S_OK)
{
// Do some error handling... (later)
return varResult.scode;
}
}
}
delete [] pvars;
return varResult.scode;
}
這個問題可能是這里提出的問題的重復: ATL COM:從其他線程訪問事件方法 。 但是說句公道話,當我開始搜索時-我不知道搜索正確的單詞。 謝謝。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.