我有一个程序,我通过国家仪器 (NI) 的 ADC 系统记录数据。
设备将信息缓冲一段时间,然后程序在某个时间点收集缓冲区数据。如果程序收集的数据大于缓冲区,那么缓冲区将不得不在我的程序没有接收到数据的情况下释放,这将导致 NI 库抛出异常,指出请求的数据不再可用,因为它已丢失。
由于我的程序是命令提示程序,如果用户单击并按住滚动条,程序会暂停,这可能会导致此问题发生。
如何在不增加缓冲区大小的情况下解决这个问题?我可以在 Windows 中禁用这个持有的东西吗?
谢谢。
我有一个程序,我通过国家仪器 (NI) 的 ADC 系统记录数据。
设备将信息缓冲一段时间,然后程序在某个时间点收集缓冲区数据。如果程序收集的数据大于缓冲区,那么缓冲区将不得不在我的程序没有接收到数据的情况下释放,这将导致 NI 库抛出异常,指出请求的数据不再可用,因为它已丢失。
由于我的程序是命令提示程序,如果用户单击并按住滚动条,程序会暂停,这可能会导致此问题发生。
如何在不增加缓冲区大小的情况下解决这个问题?我可以在 Windows 中禁用这个持有的东西吗?
谢谢。
只有试图输出到控制台的线程才会被阻塞。将此作为单独的线程,您的问题就会消失。
当然,您需要缓冲输出,并在缓冲区溢出时做一些明智的事情。
作为参考,这是我用来测试它的简单代码,您会注意到即使按住滚动条,计数器也会继续增加:
#include <Windows.h>
#include <stdio.h>
volatile int n = 0;
DWORD WINAPI my_thread(LPVOID parameter)
{
for (;;)
{
n = n + 1;
Sleep(800);
}
}
int main(int argc, char ** argv)
{
if (!CreateThread(NULL, 0, my_thread, NULL, 0, NULL))
{
printf("Error %u from CreateThread\n", GetLastError());
return 0;
}
for (;;)
{
printf("Hello! We're at %u\n", n);
Sleep(1000);
}
return 0;
}
虽然可能有一些方法可以绕过您可能想到的输出的每个单独问题[包括例如在有时慢的输出链接上通过网络运行它,或类似的],但我认为正确的做法是断开您的输出从您收集的数据中。通过添加一个单独的线程来收集数据,并将主线程显示到命令提示符窗口,应该不难做到这一点。这样,无论 Windows 向您抛出哪种“输出被阻止”的变体,它都会起作用 - 至少在您用完 RAM 之前,但此时这是您的程序决定做某事的决定 [例如丢弃一些数据或一些这样的]。
“我需要收集一些东西,我也需要允许用户查看数据,但我不希望两者相互干扰”的问题一般是这样解决的。
首先使用GetConsoleWindow winapi 函数并获取控制台的 HWND。现在我建议两种方法来做到这一点,
方法 I 通过创建您自己的 WindowProcedure 将窗口子类化。(从这里获得帮助)现在您已经对它进行了子类化,您可以拦截WM_VSCROLL和 WM_HSCROLL 消息并对您的代码进行自己的补救。
方法二使用SetWindowPos 等函数来改变窗口的大小,这样就不需要滚动条了。或更改控制台屏幕缓冲区的大小,以便不需要滚动条。
方法 I 对应用程序有很多控制,但它比方法 II 稍微复杂一点,方法 II 非常简单。如果要禁止用户调整控制台窗口的大小,只需WS_THICKFRAME
从控制台窗口的WindowStyle中删除 。
我遇到了类似的情况,发现这种阻塞行为可能是由命令提示符的快速编辑“功能”引起的。这个问题解释了它,答案显示了如何禁用它。希望这会有所帮助,即使在几年之后:)