【发布时间】:2011-12-28 14:09:19
【问题描述】:
我有 C++ 库 (Win32 Console),我在其中使用计时器实现了异步函数。异步方法返回设备信息。
我创建了一个单独的线程“定时器线程”来创建一个隐藏窗口,然后我调用SetTimer(),然后调用实现的消息循环。
当计时器到期时,它会启用回调。
当我在控制台应用程序中使用该库时,它运行良好。
在MFC 应用程序中,我正在发布消息以在回调触发时更新用户界面。发布消息无效。
如果我删除库中的消息循环,它在 MFC 应用程序中工作正常。
我得出的结论是:
我猜这个问题是由于两个消息循环,一个 MFC(主线程)和 TimerThread 消息循环。所以当回调被调用,后续的PostMessage导致TimerThread消息循环,在MFC(主线程)消息循环中不报。
如果我删除 TimerThread 消息循环,那么它在 MFC 应用程序中工作正常,但在控制台应用程序中无法工作。
我该如何克服这个问题?
class IDeviceEnumerationCallback
{
public:
virtual void onDeviceDiscovered(DeviceInfo* pDeviceInfo,unsigned short nNoOfDevice) = 0;
};
class IDeviceDiscovery
{
public:
virtual int InitialiseDiscovery(IDeviceEnumerationCallback*) = 0;
virtual void UnInitialiseDiscovery() = 0;
virtual int EnumerateDevice() = 0;
};
class CDeviceDiscovery:IDeviceDiscovery
{
//Implementation
}
在 MFC/控制台应用程序中,我正在实现 IDeviceEnumerationCallback 以获取回调。
我正在使用 Bonjour API 来枚举设备,并且 Bonjour API 中的所有方法都是回调。
我正在等待一段时间来使用 Bonjour API 枚举设备,然后在 400 毫秒后说我正在调用回调以返回结果。在调用回调的 MFC 应用程序中,我正在做一个PostMessage() 来更新用户界面。
之前我尝试不使用 Windows 消息泵。我有一个SetTimer 函数,它与MFC 应用程序一起工作,但对于控制台应用程序,回调永远不会被调用,所以我在这里实现了一个消息泵。现在它不适用于 MFC 应用程序。
【问题讨论】:
-
将消息从一个线程发布到另一个线程/消息循环管理的窗口应该没问题。假设句柄是正确的,则应使用消息 OK 调用 WindowProc。 PostMessage() 返回什么?
-
SetTimer以扭曲和容易出错而闻名。消息不会发布,而是仅在您调用GetMessage时创建,但不会在队列中已经有高优先级消息时创建(不是开玩笑!)。使用可等待的计时器。