2015-03-31 113 views
0

我有一個應用程序使用三個輔助線程從數據庫中讀取(3個不同的表,總共約160,000行),從這些行創建對象,然後將對象添加到兩個列表中的一個取決於創建的對象類型。輔助線程通過SendMessage調用將對象添加到列表中,以便主線程是添加到/從列表中刪除的唯一對象。SendMessage - 奇怪的返回值

奇怪的是,SendMessage並不總是成功,我會經常得到這兩個錯誤ERROR_ALREADY_EXISTS(183)和ERROR_TRUSTED_DOMAIN_FAILURE(1788)。 SendMessage調用的函數只是將一個對象添加到列表中,並且此函數始終返回成功(0)。沒有創建文件(如ERROR_ALREADY_EXISTS似乎建議),並且沒有網絡調用,所以我不知道爲什麼我收到ERROR_TRUSTED_DOMAIN_FAILURE錯誤。

關於什麼可能導致這些錯誤或任何方式來調試這些錯誤的任何想法?

作爲一個說明,在它是SendMessage之前,我使用PostMessage並且會得到大量的ERROR_NOT_ENOUGH_QUOTA錯誤; SendMessage使公用事業工作更好。

+0

如果我做PostMessage,我仍然可以使用GetLastError()嗎?我喜歡線程安全的數組方法,謝謝。 – riqitang 2015-03-31 15:49:31

+0

@HansPassant你是什麼意思?它說,我仍然處理「非排隊傳入消息」(是其他SendMessage()?)的部分? – andlabs 2015-03-31 16:02:25

+0

這隻適用於工作線程創建自己的窗口並具有消息隊列的情況。這裏不太可能適用。 – 2015-03-31 16:20:19

回答

3

SendMessage()返回發送的消息的結果。由消息處理器決定發送代碼實際返回的值是SendMessage()GetLastError()是唯一有意義的,如果SendMessage()本身失敗,你必須使用SetLastError()來檢測,比如:如果目標HWND不同的線程比正在調用一個擁有

SetLastError(0); 
LRESULT res = SendMessage(...); 
if ((res == 0) && (GetLastError() != 0)) 
{ 
    // send failed, for example GetLastError()=ERROR_ACCESS_DENIED if UIPI blocked the message ... 
} 
else 
{ 
    // send succeeded, res is whatever value the message handler returned ... 
} 

這隻適用可靠SendMessage()。不能跨線程邊界影響GetLastError()。在消息處理程序中對SetLastError()的任何調用都將影響HWND擁有線程的錯誤代碼,而不會影響發送線程的錯誤代碼。

然而,如果目標HWND同一線程正在調用SendMessage(),和消息處理程序發生(通過失敗API調用直接,或間接地)來調用SetLastError()擁有設置一個非零錯誤代碼,並且發生了返回0作爲其結果值爲SendMessage()返回給發件人,那麼我可以想到的唯一方法是讓發件人區分由GetLastError()返回的錯誤代碼是否由SendMessage()本身設置失敗,或由消息處理程序設置,是通過SetWindowsHookEx()使用線程區域設置消息掛鉤來檢測消息手實際上是否被調用(我唯一能想到的情況是如果目標HWND無效,所以SendMessage()找不到它的窗口過程)。

您可以使用GetWindowThreadProcessId()GetCurrentThreadId()來檢查目標HWND是否屬於調用線程。

+0

但這可靠嗎?沒有什麼能阻止我的信息做同樣的事情。或者我誤解了你想表達的內容? – andlabs 2015-03-31 22:53:05