2 Stimmen

Form.Invoke friert die Benutzeroberfläche ein

Ich habe etwa eine Stunde lang herumgegoogelt und immer noch keine Lösung gefunden.

Ich versuche einfach, den maximalen Wert eines Fortschrittsbalkens aus einem anderen Thread einzustellen. So habe ich die Methode Control.Invoke gefunden. Ich bin vorgegangen und habe sie implementiert:

enter image description here

Wenn ich jetzt meine App debugge, bleibt sie einfach bei der this.Invoke Linie. Die Benutzeroberfläche wird angezeigt, und sie ist eingefroren. Ich habe also weiter gegoogelt und mir wurde gesagt, dass ich Folgendes verwenden soll this.BeginInvoke() . Ich implementierte es, und ich war in Ordnung, die UI nicht einfrieren. Das ist ganz nett, aber in der Tat der maximale Wert meines Fortschrittsbalken hat sich nicht ändern :(

Was mache ich falsch?

EDIT: Vielleicht hilft das: Ich verwende Parallel.Invoke(); um meinen Thread zu verwalten ...

5voto

Nick Butler Punkte 23397

Control.Invoke wird nur blockiert, wenn es auf einem Worker-Thread aufgerufen wird und der UI-Thread blockiert ist.

Der von Ihnen gepostete Code ist korrekt. Sie müssen den UI-Thread irgendwo anders blockieren.

2voto

seanzi Punkte 873

Ich verwende etwas Ähnliches in meiner Anwendung, mit der ich den aktuellen Wert für den Fortschrittsbalken aktualisiere. Ich habe es gegenüber Ihrem Beispiel ein wenig verändert. Probieren Sie es aus und sehen Sie, ob es hilft :)

    public void SetMax(int value)
    {
        if (this.ProgressBar_status.InvokeRequired)
        {
           this.BeginInvoke(new Action<int>(SetMax), value);
           return;
        }
        this.ProgressBar_status.Maximum = value;
    }

0voto

VSS Punkte 7962

Ich würde vorschlagen, dass es besser ist, eine Background Worker-Komponente zu verwenden, die die Meldung des Fortschritts in der Fortschrittsleiste und andere Funktionen unterstützt, anstatt invoke und BeginInvoke aufzurufen. Weitere Details über Background Worker finden Sie unter dem folgenden MSDN-Link:

http://msdn.microsoft.com/en-us/library/c8dcext2.aspx

0voto

Roly Punkte 1

Ich hatte das gleiche Problem, und dank der Antwort von Nicholas habe ich erkannt, dass ich in einer GUI-Anwendung zum Debuggen einer Klasse, die in einem Windows-Dienst verwendet wird, in die gleiche Falle getappt bin. Die Dienstklasse führt den größten Teil ihres Codes in einem Thread aus. Der Thread rief eine Protokollierungsprozedur auf, wenn er angehalten wurde. Ich hielt ihn mit einer Schaltfläche an, und die Protokollierung benutzte invoke, um ein Textfeld zu aktualisieren. Das Problem war so einfach, dass ich mich selbst getreten habe - invoke wartete darauf, dass der Button-Klick beendet wurde, was wiederum darauf wartete, dass die Klasse anhielt, was wiederum darauf wartete, dass invoke protokollierte, dass es anhielt (Wiederholung, bis der Task-Manager den Prozess beendet). Gelöst durch die Erstellung eines Threads in der Stop-Taste klicken, mit einem threadproc, um die Service-Klasse zu stoppen. Dies bedeutete, dass ich mehr Code zum Aktualisieren der Form setzen musste nach den Stopp in einem anderen Aufruf aus dem neuen Thread, aber das funktionierte gut, da es nicht auf den Hauptformular-Thread wartete.

0voto

8Unlimited8 Punkte 157

In meinem Fall war der Fehler, die join() nach dem Start des Threads. join() verhindert, dass der Hauptthread Codes ausführt, bevor der Child-Thread abgeschlossen ist. Ich habe den join()-Befehl entfernt und die Codes nach join() in den Thread verschoben, und alles hat gut funktioniert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X