Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 优雅地杀死一个visualc++;串行线程 我有一个Visual Studio C++ 2013 MFC应用程序,它从串行旋转编码器写入/读取数据,并将读取数据发送到步进电机。读数在一段时间内(flagTrue){}。while循环在单独的线程中缠绕_Multithreading_Mfc_C++ Cli - Fatal编程技术网

Multithreading 优雅地杀死一个visualc++;串行线程 我有一个Visual Studio C++ 2013 MFC应用程序,它从串行旋转编码器写入/读取数据,并将读取数据发送到步进电机。读数在一段时间内(flagTrue){}。while循环在单独的线程中缠绕

Multithreading 优雅地杀死一个visualc++;串行线程 我有一个Visual Studio C++ 2013 MFC应用程序,它从串行旋转编码器写入/读取数据,并将读取数据发送到步进电机。读数在一段时间内(flagTrue){}。while循环在单独的线程中缠绕,multithreading,mfc,c++-cli,Multithreading,Mfc,C++ Cli,它确实起到了作用,但当我试图优雅地退出应用程序时,我不断得到以下信息: “System.ObjectDisposedException”mscorlib.dll 我试着将计时器设置为1-2秒,让串行侦听完成,但似乎即使我似乎已经退出线程,侦听仍在继续。以下是代码片段: //this is inside of the main window CDlg class pSerialThread = (CSerialThread*)AfxBeginThread(RUNTIME_CLASS(CSerial

它确实起到了作用,但当我试图优雅地退出应用程序时,我不断得到以下信息:

“System.ObjectDisposedException”mscorlib.dll

我试着将计时器设置为1-2秒,让串行侦听完成,但似乎即使我似乎已经退出线程,侦听仍在继续。以下是代码片段:

//this is inside of the main window CDlg class
pSerialThread = (CSerialThread*)AfxBeginThread(RUNTIME_CLASS(CSerialThread)); 

//this is inside the CSerialThread::InitInstance() function
init_serial_port();

//this is the serial listening while loop
void init_serial_port() {
SerialPort^ serialPort = gcnew SerialPort();
while (bSerialListen) {
//do read/write using the serialPort object
}
serialPort->Close();
}

///this is in the OnOK() function
bSerialListen = false;
pSerialThread->ExitInstance();
Hans在下面的回答中提出了一个不完整的解决方案,即在端口关闭后让线程重置一个标志:

SerialPort^ serialPort = gcnew SerialPort();
serialIsOpen = true;
while (bSerialListen) {
//do read/write using the serialPort object
}
serialPort->Close();
serialIsOpen = false;
}
然后在OnOK()内(这会导致干净的退出):

但是,用户总是必须按退出两次,因为下面的操作永远不起作用

while (serialIsOpen) {
    Sleep(100);
    //safety counter, do not proceed to OnOK();
    }
OnOK();
而在端口重置标志之前过期,即使等待10秒,也要比用户按两次按钮的时间长得多:

 while (bSerialListen) {
非常麻烦。首先,从长远来看,bool不是一个合适的线程同步原语。其次,最可能的问题是,您的代码没有检查它。因为线程实际上被困在SerialPort::Read()调用中。它没有完成,因为设备在您想要终止程序的时候没有发送任何内容

接下来发生的事情很少是优雅的。触发不可修补的ObjectDisposedException的一个好方法是猛拉USB接口。当你看到它不起作用并且不知道下一步该做什么时,你唯一能做的事情就是。好主意。这让许多USB驱动程序厌恶地举手,它知道userland应用程序已经打开了端口,但它已经不在了,现在开始拒绝任何请求。有时甚至不能满足要求,非常不愉快。没有办法以优雅的方式做到这一点,串行端口不是即插即用设备。这将触发SerialPort开始引发事件的工作线程中的ODE,这是不可调度的

决不,决不,决不使用“安全移除硬件”托盘图标猛拉USB接口,对于串行端口等传统设备来说,这是一项极其严格的要求。不要勉强

那么接下来该怎么办呢?完成SerialPort::Read()调用的唯一优雅方法是猛拉地板垫。您必须调用SerialPort::Close()。您仍然会得到一个ObjectDisposedException,但现在您可以实际捕获它。立即退出循环,不做任何其他事情,让线程终止

但是当然,你必须从另一个线程执行,因为这个线程被卡住了。做这件事有很多麻烦毫无疑问,当您使用MFC时,希望它退出的线程在您的程序中不是托管线程。听起来你已经发现了


更好的方法是在阅读之后你可能会觉得可以接受的方法。不要这样做。

看起来托管的
SerialPort
类在被释放时/之后正在被访问。你使用什么语言来管理/管理非交互式?对不起,我有一个英国键盘在美国PC…Visual C++,使用命名空间系统;使用名称空间System::IO::Ports;那么,你用的是什么语言?C++/CLI?管理C++?还有什么吗?如果我的答案很愚蠢,我很抱歉,当我在上面写到visual studio 2013中的VC++时,我认为这已经足够了。我想我错了。在Project Properties_C/C++/General中,我必须启用/clr以使串行端口对象可识别,这就是我所知道的:)。能否将Visual Studio设置为在
ObjectDisposedException
上中断,并查看堆栈跟踪?这应该能准确地告诉您在处理对象之后访问的对象以及从何处访问的对象。谢谢,Hans。如果有帮助的话,我会让while循环进入睡眠状态(5),就像编码器附带的示例一样。编码器以100Hz的频率读取/写入数据(使用while循环每次迭代的时间戳测量)。因此,我假设如果我将全局标志bSerialListen设置为false,线程将在0.01秒内看到它,并在while{}循环之外继续执行SerialPort::Close()。但它似乎不起作用。我可以捕获ObjectDisposedException,但是,再次强调,退出循环的唯一方法是将BSerialisten设置为false,因此我回到了开始的地方。我已经告诉过您使用bool是不正确的,例如ManualResetEvent。你没有用我的建议,祝你好运。好吧,我想我只能用我现在能理解的。毕竟,只有一句话专门用来形容布尔的存在,其余的都用来形容优雅地退出是多么重要。所以,现在,我有一个学生正在使用她的显微镜,没有看到错误信息。
 while (bSerialListen) {