Entwickler-Ecke
WPF / Silverlight - BackgroundWorker + While (+ BeginInvoke) = Freeze
Mayhem - Sa 19.07.14 23:35
Titel: BackgroundWorker + While (+ BeginInvoke) = Freeze
Hey Comunity :)
Ich versuche mich gerade an einem kleinem Projekt und habe folgendes Problem:
Ich habe ein WPF Projekt mit Microsoft Visual C# 2010 (Zielframework: .NET Framework 4 Client Profile) aufgesetzt und mit 2 Textboxen sowie 2 Buttons versehen...
Die Textboxen sind für Start und Ende gedacht...
Der Erste Button führt die Schleife Von "Start" bis "Ende" aus.
Und der zweite Button gibt eine MessageBox aus.
Jetzt möchte ich, dass der erste Button meine While-Schleife startet aber die UI nicht freezt und man den zweiten Button, der eine MessageBox ausgibt weiterhin klicken kann... Das krieg ich aber irgendwie leider nicht hin... :(
Hoffe, dass ihr mir weiterhelfen könnt oder einen Link zum lesen habt ;)
Ich finde nämlich irgendwie nichts... suche jetzt schon 2 Tage nach einer lösung dafür...
Oder ich bin einfach zu dämlich für Google & Suchfunktionen ^^''
Danke im Vorraus für eure Antworten!
Mayhem
Hier mal der Code von der MainWindow.xaml:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:
| using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.ComponentModel;
namespace whiletest { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); }
private void button1_Click(object sender, RoutedEventArgs e) { var worker = new BackgroundWorker(); worker.DoWork += worker_DoWork; worker.RunWorkerAsync(); } private void worker_DoWork(object sender, DoWorkEventArgs e) { int i = 0; this.Dispatcher.BeginInvoke(new Action(delegate() { while (Convert.ToInt32(textBox1.Text) < Convert.ToInt32(textBox2.Text)) { textBox1.Text = i.ToString(); i++; } })); }
private void button2_Click(object sender, RoutedEventArgs e) { MessageBox.Show("Ich bin eine MessageBox"); } } } |
und hier die SRC's des Projekt's:
http://85.214.124.247/whiletest.zip
Moderiert von
Th69: Code- durch C#-Tags ersetzt
Mayhem - Mo 21.07.14 03:36
Hey :)
Danke für deine Antwort.
Leider verstehe ich nicht, wie mir da ein Timer helfen kann :o
Hättest du vielleicht ein kleines Beispiel, wie es mir in dem Zusammenhang helfen kann?
- Bin leider noch ein kleiner Anfänger im programmieren :)
Das ich durch das Invoke den Thread zurück an die GUI sende, wusste ich bereits ;)
Ich hätte vielleicht besser beschreiben sollen, was mein Problem ist ^^
Problem ist halt, dass ich ohne das Invoke leider nicht auf die TextBoxen zugreifen kann und eine Fehlermeldung ausgelöst wird, was ja aber auch klar ist, weil ich vom Thread aus auf die GUI zugreifen will.
Jetzt möchte ich halt gern wissen, wie ich auf die TextBoxen der GUI zugreifen kann, ohne ein Invoke ausführen zu müssen, weil ja sonst die GUI wieder freezt ^^
Hoffe es ist jetzt etwas klarer und danke weiterhin für jeden tipp :)
Th69 - Mo 21.07.14 09:20
Hallo Mayhem,
deine jetzige Schleife blockiert das gesamte Programm, weil du damit die Prozessorlast (bzw. Kernlast) auf 100% setzt, da du keine Wartefunktion drin hast (z.B. ein Thread.Sleep()).
Was genau möchtest du denn mit deiner Schleife erreichen (denn bisher zählt das Programm, so schnell der Rchner kann, den Zähler hoch und gibt ihn in der TextBox aus - und das blockiert halt!)?
Ein Timer hilft, daß eine wiederkehrende Aufgabe (z.B. die Ausgabe) mit einen bestimmten Intervall (z.B. jede 1/10 Sekunde, jede Sekunde oder auch jede Minute etc.) ausgeführt wird. Der Anwender kann sowieso nicht mehr als ca. 25 Änderungen pro Sekunde verfolgen (entspricht ca. den Filmframes)!
PS. Ein Invoke wirst du bei jeder GUI-Aktion aus einem anderen Thread ausführen müssen. Ein Timer dagegen läuft im selben Thread, d.h. da brauchst du kein Invoke!
Mayhem - Mi 23.07.14 19:46
Hey Th69,
erstmal sorry, dass ich so lang auf meine Antwort hab warten lassen (Hatte viel zu tun)...
Danke für die Erklärung!
Ich werde mir das ganze dann nochmal mit nem (Dispatcher)Timer anschauen und testen.
Falls ich nicht weiter komme, meld ich mich wieder :)
Zitat: " Ein Timer dagegen läuft im selben Thread, d.h. da brauchst du kein Invoke! "
Das wusste ich zum Beispiel noch nicht...
Ich dachte ein Timer blockiert genauso ^^''
Man lernt immer was dazu!
Danke nochmal für die Hilfestellung :D
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!