我有一个正在检查串口通信的后台工作者,但我想在用户点击关闭串口按钮时停止它。 后台工作者的代码:
private: System::Void backgroundWorker1_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
while (true)
{
try {
String^ tempVal = Arduino->ReadLine();
this->SetText(tempVal);
Arduino->DiscardInBuffer();
if (this->backgroundWorker1->CancellationPending) {
e->Cancel = true;
this->Arduino->Close();
this->pictureAClose->Visible = false;
return;
}
}
catch (TimeoutException^) {
}
}
}
关闭端口按钮:
private: System::Void pictureAClose_Click(System::Object^ sender, System::EventArgs^ e) {
this->backgroundWorker1->CancelAsync();
}
现在,当你点击关闭端口按钮时,它什么都不做。
答案 0 :(得分:0)
同意Johnny Mopp。 ReadLine()很可能是阻塞的,这会阻止该方法进入if (this->backgroundWorker1->CancellationPending)
子句。因此,取消该任务不会导致该呼叫退出。
看起来Arduino
有Close()
方法。如果“Arduino”设计正确,则调用Close()
会导致阻止ReadLine()
调用退出异常(ObjectDisposed
或类似内容)。因此,将Click处理程序更改为以下内容:
System::Void pictureAClose_Click(System::Object^ sender, System::EventArgs^ e)
{
this->backgroundWorker1->CancelAsync();
Arduino->Close();
}
(实际上,我会在try/catch
电话周围加Close()
以防万一。)
请注意,您还需要向工作线程方法的Exception ^
块添加更通用的try/catch
子句,以捕获除超时之外的其他异常。
我注意到了其他可能导致问题的因素。在您的线程方法中,您有以下内容:
this->SetText(tempVal);
这可能会引发一个摇摆(异常),因为它不会在主Form的线程上下文中执行此操作。您必须执行Invoke
才能在同步上下文中执行此行代码。
此外,根据您的语法,这也可以在“c ++ - cli”
下标记