gpt4 book ai didi

windows - 一段时间后收不到消息

转载 作者:可可西里 更新时间:2023-11-01 13:27:22 31 4
gpt4 key购买 nike

我正在使用 JNA 来访问 User32 函数(我认为这与这里的 Java 无关,更多的是概念问题)。在我的应用程序中,我有一个与 Canon SDK 通信的 Java 进程。要发送任何消息,我正在使用以下函数:

private void peekMessage(WinUser.MSG msg) throws InterruptedException {
int hasMessage = lib.GetMessage(msg, null, 0, 0);
if (hasMessage != 0) {
lib.TranslateMessage(msg);
lib.DispatchMessage(msg);
}
Thread.sleep(1);
}

peekMessage 在循环中被调用,一切正常。每当从相机拍摄图像时,我都会收到事件并执行其余操作。

但我观察到,在大约 15 秒(有时从不或有时刚开始)相机没有任何事件后,拍照不会给我任何下载事件。后来整个应用程序变得不可用,因为它没有从相机获取任何事件。

这可能是什么原因?请让我知道任何其他需要的信息,我可以粘贴相应的代码。

编辑:

初始化:

Map<String, Integer> options = new HashMap<String, Integer>();
lib = User32.INSTANCE;
hMod = Kernel32.INSTANCE.GetModuleHandle("");
options.put(Library.OPTION_CALLING_CONVENTION, StdCallLibrary.STDCALL_CONVENTION);
this.EDSDK = (EdSdkLibrary) Native.loadLibrary("EDSDK/dll/EDSDK.dll", EdSdkLibrary.class, options);


private void runNow() throws InterruptedException {

while (!Thread.currentThread().isInterrupted()) {
Task task = queue.poll();
if (task != null) {
int taskResult = task.call();
switch (taskResult) {
case (Task.INITIALIZE_STATE):
break;
case (Task.PROCESS_STATE):
break;
case (Task.TERMINATE_STATE): {
//queue.add(new InitializeTask());
Thread.currentThread().interrupt();
break;
}
default:
;
}
}
getOSEvents();
}
}
WinUser.MSG msg = new WinUser.MSG();

private void getOSEvents() throws InterruptedException {
if (isMac) {
receiveEvents();
} else {
peekMessage(msg);
}
}

上面,每当我得到我的相机事件时,它都会将它添加到 queue 并且在每个循环中我检查 queue 以处理任何 Task。一个更重要的信息:这是一个在 cmd 上运行的进程,没有窗口。我只需要相机中的事件,不需要其他任何东西。

注册回调函数的代码:

/**
* Adds handlers.
*/
private void addHandlers() {
EdSdkLibrary.EdsVoid context = new EdSdkLibrary.EdsVoid(new Pointer(0));
int result = EDSDK.EdsSetObjectEventHandler(edsCamera, new NativeLong(EdSdkLibrary.kEdsObjectEvent_All), new ObjectEventHandler(), context).intValue();
//above ObjectEventHandler contains a function "apply" which is set as callback function

context = new EdSdkLibrary.EdsVoid(new Pointer(0));
result = EDSDK.EdsSetCameraStateEventHandler(edsCamera, new NativeLong(EdSdkLibrary.kEdsStateEvent_All), new StateEventHandler(), context).intValue();
//above StateEventHandler contains a function "apply" which is set as callback function


context = new EdSdkLibrary.EdsVoid(new Pointer(0));
result = EDSDK.EdsSetPropertyEventHandler(edsCamera, new NativeLong(EdSdkLibrary.kEdsStateEvent_All), new PropertyEventHandler(), context).intValue();
//above PropertyEventHandler contains a function "apply" which is set as callback function

}

最佳答案

您正在从属于该线程的所有窗口获取所有消息,包括所有鼠标移动、绘画等。如果您不快速调用此函数,您的消息队列将溢出并导致您描述的行为。

如果没有消息在等待,您绝对不希望休眠,因为 GetMessage 会产生。

因此,如果在该线程窗口的其他地方存在一个正常的消息泵(即 GetMessage/DispatchMessage)循环,那么您应该让该泵完成大部分工作,也许使用 wMsgFilterMin、wMsgFilterMax 来获取您需要的事件信息;或者在这种情况下更好地使用带有 PM_NOREMOVE 的 peekmessage (那么你将需要 sleep 当 peekmessage 立即返回时调用)。

或者提供生成事件的窗口的 hWnd 以减少工作量。

使用 spy++ 查看此线程拥有哪些窗口以及正在生成哪些消息。

要进一步回答这个问题,请提供以下问题的答案:这个线程还在做什么,它拥有什么窗口;这个消息泵也是唯一的一个吗?还是您调用了 SDK API,它也可能在其中泵送消息?

关于windows - 一段时间后收不到消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16460205/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com