我正在嘗試構建一個dll(在Clr風格中)來提供帶有盤中股票報價的Windows應用程序。該DLL由股票應用程序加載,然後其導出的函數之一將啓動下載器/生產者來獲取數據。在第二步中,一旦dll收到數據,更新者/消費者將通過SendMessage通知股票應用程序。SendMessage不起作用
我已經在很多方面測試了下載部分按預期工作(有或沒有線程支持),所以獲取數據沒有問題。在單個迭代的情況下(下面的test1),在快照引用可用之後,更新程序成功完成其任務,並且Windows UI得到更新。現在爲了不斷得到新的引號,我把下載器和更新器函數調用放在一個循環中(下面的test2)。這一次,下載程序連續工作,但更新程序中的SendMessage掛在那裏,而Windows UI未更新,直到它退出循環。
下面是測試代碼和更新代碼(讓我們拋開downloder,因爲我們知道這是工作):
// test1: single iteration, sequential, simple insert only
// result: will update the stock app after quote download
void test1(HWND hwnd, UINT Msg)
{
producer->DownloadStocks();
prepareData(hwnd, Msg, 100);
}
// test2: one iteration of insert followed by updates upon quote download
// result: will update the stock app ONLY after it is out of the while loop
// update in test1 is blocked, too.
void test2(HWND hwnd, UINT Msg)
{
test1(hwnd, Msg);
int i = 0;
while (i<10)
{
producer->DownloadStocks();
prepareData(hwnd, Msg, 100);
i++;
}
}
void prepareData(HWND hwnd, UINT Msg, int timeout)
{
DateTime origin = DateTime(1970, 1, 1, 0, 0, 0, 0);
RCV_DATA rcv_data;
float vv = 0;
rcv_data.m_bDISK = FALSE;
rcv_data.m_nPacketNum = 1;
rcv_data.m_wDataType = RCV_REPORT;
RCV_REPORT_STRUCTEx data;
data.m_fBuyPrice[1] = 0;
data.m_fBuyVolume[1] = 0;
......
data.m_wMarket = (WORD)NQ_MARKET_EX;
while (consumer->received_data())
{
Console::WriteLine("*********************************");
while (consumer->NextRow())
{
sprintf(data.m_szLabel, "%s", consumer->GetValue("symbol"));
.......
data.m_fSellPrice[0] = getVal("ask");
data.m_fSellVolume[0] = getVal("asksize");
rcv_data.m_pReport = &data;
printf("\nsending update for %s", data.m_szLabel);
SendMessage(hwnd, Msg, (WPARAM)RCV_REPORT, (LPARAM)&rcv_data);
}
}
}
我知道SendMessage函數是SYNCHR模式。它是被某些東西阻擋還是消息處理太慢?我能做些什麼來解決這個問題?我應該考慮對下載器和更新器進行線程化嗎?任何幫助,將不勝感激。
你的窗口在下一個Paint事件上得到更新,如果線程空閒,它將能夠處理它。在單線程中,只有在你的循環/函數完成後,它才能獲得/處理其他事件。您需要執行多線程。 –
當您使用SendMessage()時,死鎖是常見的危險。你需要使用調試器,找出擁有窗口的線程正在做什麼。總是喜歡PostMessage()。 –
@Ashish Negi,我嘗試使用消費者/生產者模式的pthread。它不會工作。 – Ben