Snees (07.03.2013)
-
07.03.2013, 14:47 #1
Methode "im Hintergrund" ausführen
Hallo, folgende Situation:
Ich habe eine Windows-Form mit einem Button und einem Label,
bei einem Klick auf den Button wird folgender Code ausgeführt:
for (int i = 1; i <= 100; i++)
{
label1.Text = i.ToString();
System.Threading.Thread.Sleep(100);
}
Mein Problem ist, dass sich die Form "aufhängt", während diese Schleife durchlaufen wird, man keinen anderen Button mehr klicken kann und ich nicht die Veränderung des Label-Textes sehen kann, sondern dort direkt 100 steht nachdem die Schleife durchlaufen wurde.
Derartige Projekte habe ich bis jetzt immer mit einer Konsolenanwendung realisiert, weil dort die Ausgabe so aussehen würde:
1
2
3
4
5
6
7
Ich hoffe ich habe mich verständlich ausgedrückt.
-
07.03.2013, 15:03 #2
- Registriert seit
- 19.11.2011
- Beiträge
- 496
Thanked 412 Times in 268 PostsAW: Methode "im Hintergrund" ausführen
Dein GUI hängt sich auf, weil du alles in einem Thread ausführen lässt.
GUI-Kram kommt in einen Thread, Logik in einen anderen.
Schau mal hier:
Threading (C#)
-
The Following User Says Thank You to Mr. White For This Useful Post:
-
07.03.2013, 15:28 #3
AW: Methode "im Hintergrund" ausführen
Okay, danke.
Wenn ich die Methode in einem neuen Thread starte bekomme ich folgenden Fehler:
Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement label1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread newThread;
newThread = new System.Threading.Thread(this.dothatshit);
newThread.Start();
MethodInvoker updateCounterDelegate = new MethodInvoker(dothatshit);
Invoke(updateCounterDelegate);
}
private void dothatshit()
{
for (int i = 1; i <= 100; i++)
{
label1.Text = i.ToString();
System.Threading.Thread.Sleep(100);
}
}
}
}
Wenn ich das Programm so ausführe habe ich das gleiche Problem wie eben, GUI hängt sich auf und springt auf 100 und dann bekomme ich noch die oben genannte Fehlermeldung...
-
07.03.2013, 15:40 #4
- Registriert seit
- 19.11.2011
- Beiträge
- 496
Thanked 412 Times in 268 PostsAW: Methode "im Hintergrund" ausführen
Ob du es richtig eingesetzt hast, weiß ich nicht. Ich habe nur soviel Ahnung von C# wie es die Ähnlichkeit zu Java zulässt. ^^
Aber habe dir mal was herausgesucht: [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) | FAQ | myCSharp.de - DIE C# und .NET Community
-
The Following User Says Thank You to Mr. White For This Useful Post:
Snees (07.03.2013)
-
07.03.2013, 16:25 #5
AW: Methode "im Hintergrund" ausführen
Das hat mir geholfen, hier meine Lösung:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread newThread;
newThread = new System.Threading.Thread(this.dothatshit);
newThread.Start();
}
private void dothatshit()
{
for (int i = 1; i <= 100; i++)
{
label1.Invoke(new MethodInvoker(updateLabel));
updateLabel();
System.Threading.Thread.Sleep(100);
}
}
private void updateLabel()
{
Random random = new Random();
int randomNumber = random.Next(0, 3);
if (randomNumber == 0)
{
label1.Text = "0";
}
else if (randomNumber == 1)
{
label1.Text = "1";
}
else if (randomNumber == 2)
{
label1.Text = "2";
}
else if (randomNumber == 3)
{
label1.Text = "3";
}
else
{
label1.Text = "4";
}
}
}
}
-
07.03.2013, 18:51 #6
AW: Methode "im Hintergrund" ausführen
Dafür könntest du auch ein BackgroundWorker nutzen.
-
The Following User Says Thank You to uncopyable For This Useful Post:
Snees (07.03.2013)
-
07.03.2013, 21:01 #7Gelöschter BenutzerGast
AW: Methode "im Hintergrund" ausführen
Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement label1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.
Code:CheckForIllegalCrossThreadCalls = false;
Code:Form1.Invoke((MethodInvoker)delegate { //.. });
-
07.03.2013, 23:01 #8
- Registriert seit
- 15.11.2011
- Beiträge
- 7.885
- Blog Entries
- 5
Thanked 9.365 Times in 3.204 PostsAW: Methode "im Hintergrund" ausführen
Da wird überhaupt nix gefixxt, sondern nur die Exception unterdrückt, die einen vor den Risiken warnen soll.
Sobald du bei komplexeren Programmen mal ein paar Threads mehr hast wirds lustig, da können dann Deadlocks und andere witzigen Sachen auftreten die alle beteiligten Threads abschießen.
CheckForIllegalCrossThreadCall ist dafür gedacht, die Prüfung abzustellen um die Performance zu erhöhen wenn definitiv sicher ist, dass keine Threadübergreifenden Vorgänge stattfinden können. Invoken ist performancemäßig logischerweise IMMER schlechter, da die betreffenden Threads sich vorher synchronisieren müssen um eben zb Deadlocks zu vermeiden.
Wenn das Programm bei den hier geposteten 5 Zeilen bleibt ist das ganze natürlich noch nicht relevant und man könnte ohne große Probleme die Prüfung einfach abschalten. Aber sowas nem Anfänger zu empfehlen halte ich für äußerst fahrlässig, da kommt schnell der falsche Schluss bei raus dass zb Invoken vollkommen unnötig ist und man ja mit einer Zeile Code alle threadübergreifendenden Probleme 'beheben' kann. Wenn man halbwegs weiß wie Threads ablaufen und was man mit CheckForIllegalCrossThreadCalls genau bewirkt ist das was anderes, dann kann mans natürlich einsetzen. Wobei ich so an Murkserei grenzende Sachen prinzipiell nicht nutzen würde, außer es geht wirklich um Performance (da nutzt man dann tendenziell aber auch eher andere Sprachen wie C++ oder Asm).
Fehler zu unterdrücken ist generell keine besonders gute Idee.
-
The Following 3 Users Say Thank You to DMW007 For This Useful Post:
Grammatikfehler (08.03.2013), Sky.NET (07.03.2013), ThunderStorm (08.03.2013)
-
08.03.2013, 02:38 #9
AW: Methode "im Hintergrund" ausführen
Um alles mal in einem Button zu haben, kann man natürlich machen wie man will.
Code:private void button1_Click(object sender, EventArgs e) { new Thread(delegate() { for (int i = 1; i <= 100; i++) { this.Invoke((MethodInvoker)delegate { label1.Text = i.ToString(); }); Thread.Sleep(100); } }).Start(); }
-
Ähnliche Themen
-
Java keine Funktion da keine "Ausführen Erlauben" Anfragen mehr
Von ShinjiKagawa im Forum WindowsAntworten: 3Letzter Beitrag: 11.02.2014, 09:32 -
Unterschied zwischen "ChicaPC-Shield" und "Malwarebytes Anti-Malware"?
Von Accountuser im Forum WindowsAntworten: 1Letzter Beitrag: 29.12.2013, 14:31 -
"Wer ist online" & "Forum-Mitarbeiter" stimmen nicht überein
Von Devon im Forum SupportAntworten: 2Letzter Beitrag: 29.09.2012, 15:24 -
Hacker-Angriff auf "World of WarCraft" und "Diablo 3"!
Von Waterpolo im Forum Gaming-NewsAntworten: 3Letzter Beitrag: 10.08.2012, 23:35
Diese Seite nutzt Cookies, um das Nutzererlebnis zu verbessern. Klicken Sie hier, um das Cookie-Tracking zu deaktivieren.