VC ++:Backgroundworker并没有停止

时间:2016-04-21 17:11:45

标签: visual-c++ backgroundworker

我有一个正在检查串口通信的后台工作者,但我想在用户点击关闭串口按钮时停止它。 后台工作者的代码:

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();     
}

现在,当你点击关闭端口按钮时,它什么都不做。

1 个答案:

答案 0 :(得分:0)

同意Johnny Mopp。 ReadLine()很可能是阻塞的,这会阻止该方法进入if (this->backgroundWorker1->CancellationPending)子句。因此,取消该任务不会导致该呼叫退出。

看起来ArduinoClose()方法。如果“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”

下标记