2016-04-21 16 views
0

Ich habe einen Hintergrundarbeiter, der die Kommunikation der seriellen Schnittstelle überprüft, aber ich möchte es stoppen, wenn der Benutzer auf die Schaltfläche zum Schließen der seriellen Schnittstelle klickt. Der Code der Hintergrund Arbeiter:VC++: Hintergrundarbeiter stoppt nicht

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^) { 
     } 
    } 
} 

Und die enge Port-Taste:

private: System::Void pictureAClose_Click(System::Object^ sender, System::EventArgs^ e) { 
    this->backgroundWorker1->CancelAsync();  
} 

Im Moment tut es nichts, wenn Sie in der Nähe Port klicken.

+0

Sind Sie sicher, dass 'Arduino-> Readline();' blockiert nicht? –

Antwort

0

Stimmen Sie mit Johnny Mopp überein. Die Blockierung von ReadLine() ist höchstwahrscheinlich blockiert, wodurch verhindert wird, dass die Methode die Klausel if (this->backgroundWorker1->CancellationPending) erreicht. Das Abbrechen der Aufgabe führt daher nicht dazu, dass der Aufruf beendet wird.

Es sieht aus wie Arduino hat eine Close() Methode. Wenn "Arduino" korrekt entworfen wurde, sollte der Aufruf Close() einen blockierenden ReadLine() Aufruf verursachen, mit Ausnahme (ObjectDisposed oder etwas Ähnliches) zu beenden. So Click-Handler wie diese etwas ändern:

System::Void pictureAClose_Click(System::Object^ sender, System::EventArgs^ e) 
{ 
    this->backgroundWorker1->CancelAsync();  
    Arduino->Close(); 
} 

(Eigentlich habe ich eine try/catch um diesen Close() Anruf setzen würde nur für den Fall).

Beachten Sie, dass Sie dem try/catch Block der Worker-Thread-Methode auch eine generische Exception ^-Klausel hinzufügen müssen, um andere Ausnahmen außer dem Timeout abzufangen.

Ich bemerkte etwas anderes, das Ihnen Probleme verursachen kann. Innerhalb der Thread-Methode, haben Sie die folgenden Schritte aus:

this->SetText(tempVal); 

Dies könnte eine wackelige (Ausnahme) werfen, weil es innerhalb der Hauptform des Thread-Kontext dies nicht tut. Sie müssen Invoke ausführen, um diese Codezeile in einem synchronen Kontext auszuführen.

Auch auf der Grundlage Ihrer Syntax, dies auch unter Tags versehen werden können "C++ - cli"