2011-01-14 10 views
0

Ich schreibe ein Programm, das Daten von serialport empfängt und UI-Elemente wie Textbox, Etiketten etc. aktualisiert. Timer wird verwendet, um Befehl an das Gerät häufig zu senden, als Antwort gibt Gerät einige Daten zurück, die angezeigt werden. Alles ist gut. jetzt, zwischendurch, wenn ich main form verschiebe oder es minimiere, dann läuft der thread, in dem der code läuft exit (wie ich denke). Ist es möglich, dass das Verschieben des Hauptformulars dazu führt, dass ein Thread beendet wird? Und was könnte das Problem in meinem Programm sein? Warum stoppt der Datenempfang? mögliche Lösung?Thread Exit Problem

+2

Sie haben Ihren Code nicht veröffentlicht. Aus demselben Grund konnte ich dir nicht helfen [das letzte Mal, als du diese Frage gestellt hast] (http://stackoverflow.com/questions/4667272/receiving-data-from-serialport-stops-when-main-for-is- minimiert oder verschoben). –

+1

Vielleicht einen Umriss Ihres Codes veröffentlichen? –

Antwort

0

Ihr Verhalten (Verschieben/Minimieren des Formulars) hat keinen Einfluss auf die Threads, die in den meisten Fällen im Code erstellt wurden. Der Datenthread, der die Benutzeroberfläche aktualisiert (vielleicht etwas wie myControl.Invoke), funktioniert auch, wenn Sie das Formular verschieben oder das Formular minimieren (wenn Sie jedoch das Formular schließen, ohne dass der Update-Thread abgebrochen wird, erhalten Sie Ausnahmen). Also solltest du dir keine Sorgen machen. Stattdessen denke ich, dass Sie den Code hinter dem bewegenden Ereignis oder minimierten Ereignis Ihres Formulars überprüfen müssen. Die Bereitstellung von Code ist hilfreich, um den Grund herauszufinden.

0

Es gibt ein Debugging-Fenster namens Threads. Starten Sie Ihr Programm und öffnen Sie das Thread-Fenster, wenn ein Haltepunkt erreicht wird. Wenn Ihr Thread Daten empfängt, sollten mindestens zwei Thread-IDs aufgelistet sein, der UI-Thread und der Thread, der die seriellen Daten empfängt und empfängt. Vielleicht möchten Sie Ihren Thread mit einem NAMEN versehen, damit er im Debugger einfacher zu sehen ist, da sonst nur Thread-IDs vorhanden sind. Von dort sollte dies einige Hinweise geben, warum oder zumindest wenn es austritt.

Setzen Sie Haltepunkte in Ihren Thread-Code sowie Ihren UI-Code zu überwachen. Die Frage ist ziemlich vage, aber das Debuggen und Beobachten der Threads sollte helfen.

1

Sie aktualisieren UI-Elemente in resienting thread.

Das bedeutet, dass Sie UI-Updateaufruf für Steuerelemente aufrufen müssen, da sie nicht in einem anderen Thread erstellt werden.

so, ich vermute, dass Empfänger funktioniert wie folgt:

while(!Application.IsApplicationExiting) 
{ 
    if (!serial.IsReady) break; 
    ... 
    Data data = serial.GetData(); 
    string text = GetBaudRate(data); 
    ui.Invoke((Label label) => label.Text = value, txtBauldRateLabel); 
    ... 
} 

Zu der Zeit, sollten Sie, dass in diesem Fall dieser Thread blockiert, bis der Anruf an UI Fadenenden wissen, aber interesing Teil ist Diese Aktualisierungen des UI-Threads werden auch blockiert, wenn Sie versuchen, die Größe zu ändern oder das App-Fenster zu positionieren.

Ihr UI-Thread blockiert, wenn Sie versuchen, eine Weile mit der rechten Maustaste auf eine Tite-Leiste Ihrer Anwendung zu klicken.

Sie haben also eine Sperre für den Hauptzyklus eines Empfängers, die im Falle eines Timeouts auf einem Gerät in keiner Weise blockiert werden sollte, was das Herunterfahren eines Empfängers erhöht (ändert den Status der seriellen auf nicht bereit)).

ich Rat Sie Ihre App nicht blockier Aufruf BeginInvoke() neu zu schreiben:

while(!Application.IsApplicationExiting) 
{ 
    ... 
    ui.BeginInvoke((Label label) => label.Text = value, txtBauldRateLabel); 
    ... 
} 
0

Sie den Timer-Thread sind abstürzt, weil Sie die Formular-Steuerelemente aus direkt sind aktualisieren ... Sie können‘ t tu das! Sie müssen Invoke() aufrufen, damit der Code vom Hauptthread der Benutzeroberfläche ausgeführt wird.

posted ich eine Antwort in der anderen Frage ... hier ist es wieder soweit:


Meine Vermutung ist, dass Sie Ihren Timer-Thread sind abstürzt, weil Sie nicht die Form-Steuerelemente von einem anderen aktualisieren Thread ohne Probleme ... Sie müssen einen Delegaten erstellen, der unter dem Hauptthread der Benutzeroberfläche ausgeführt wird.Sie tun dies, indem Sie Form.InvokeRequired testen und Form.Invoke aufrufen, wenn es wahr ist.

Was passiert: Ihr Timer-Thread aktualisiert die Textfelder oder andere Steuerelemente im Formular. Sie ändern die Größe oder minimieren, und die Handles dieser Formularsteuerelemente werden ungültig ... Sie können sie nicht mehr verwenden. Abgesehen davon, dass Ihr Timer-Thread noch läuft und versucht, sie zu verwenden. Absturz! Ein gutes Beispiel für Multithread-Formulare ist here. Der wichtige Teil ist:

In diesem Beispiel testen Sie InvokeRequired. Wenn es falsch ist, werden Sie auf dem Hauptthread der Benutzeroberfläche ausgeführt und können die Steuerelementeigenschaften direkt festlegen. Wenn dies der Fall ist, rufen Sie Invoke() auf und übergeben eine Funktion, die vom Haupt-UI-Thread aufgerufen wird.

In diesem Beispiel ist die Funktion/Delegat, die Sie anrufen, die gleiche Funktion wie Sie, aber das muss nicht sein. Aber Sie können ihm den Timer-Tick-Ereignishandler übergeben, damit er im Hauptthread ausgeführt wird.