2017-08-19 1 views
-1

Ich habe eine Anwendung erstellt, die ein Formular unter Verwendung Application.Run(new Form) startet. Innerhalb der Anwendung gibt es diese folgenden Thread-FunktionAusnahme beim Schließen der Anwendung geworfen

private void threadTask() { 
    while (true) { 
    Thread.Sleep(500); 
     if (isOn) { 
     Invoke((MethodInvoker) delegate { reloadData(tabControl.SelectedIndex); }); 
     Invoke((MethodInvoker) delegate { onOffButton.BackColor = Color.Lime; }); 
     Invoke((MethodInvoker) delegate { infoLabel.Visible = false; }); 
    } 
    } 
} 

Wenn ich die Anwendung schließen bekomme ich diese Ausnahme:

Ausnahme geworfen: 'System.InvalidOperationException' in System.Windows.Forms.dll

bei System.Windows.Forms.Control.Invoke (Delegatmethode, Object [] args)

Ich habe versucht, dies zu lösen, indem Sie Application.Exit() aufrufen, wenn das Formular geschlossen wird. Die Funktion wird ausgeführt, allerdings bekomme ich immer noch die Ausnahme nachdem der aufgerufen wurde.

Gibt es einen Weg, wie ich das umgehen kann? Wie überprüfe ich, dass die Anwendung geschlossen wird?

+1

Debug in vs und check wich Zeile throughs Ausnahme. Ich denke, Sie müssen beenden Fäden vor dem Beenden der Anwendung – lvl4fi4

+0

Es ist ziemlich zufällig. Ich komme mit irgendeiner der drei Invoke-Linien vor, manchmal überhaupt nicht. –

+0

so wie ich sagte, Sie müssen sie vor dem Beenden der Anwendung beenden – lvl4fi4

Antwort

2

Wenn Ihre Formulare geschlossen werden, während der Thread noch ausgeführt wird, besteht die Möglichkeit, dass einer der Aufrufe aufgerufen wird, nachdem das Formular geschlossen wurde und bevor der Thread abgebrochen wird. Dieser Aufruf versucht, den Delegaten im Kontext des UI-Threads des Formulars (das nicht mehr ausgeführt wird) auszuführen.

Lösung: Sie müssen einen Mechanismus verwenden, mit dem der Thread nicht ausgeführt werden kann (im OnClosing-Ereignis des Formulars).

Ich würde vorschlagen, eine Task (siehe https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming), die Sie mit einer CancellationToken abbrechen können.

Hinweis: In der Task müssen Sie die CancellationToken vor dem Aufruf der Invoke Methoden überprüfen, um sicherzustellen, dass sie nur aufgerufen werden, wenn keine Stornierung angefordert wird.

+2

Sie können nichts mit einem CancellationToken abbrechen. Es wird nur eine Stornierungsanfrage gespeichert. Sie können das Token fragen, wenn eine solche Anfrage gestellt wurde. Dies ist nicht auf eine Aufgabe beschränkt, Sie können es überall und in jedem Kontext tun –

+0

@Sir Rufo: Ihre Bemerkung wurde sicherlich in meine Antwort impliziert, und erklärt in den enthaltenen Link ... –

Verwandte Themen