2015-03-31 216 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