firefox1988 Member
Anmeldedatum: 08.08.2007 Beiträge: 20
|
Verfasst am: 03.05.2010, 20:46 Titel: Thread in Windows Form |
|
Servus Community,
brauch mal eure Hilfe.
Kurz zum Problem: Benutze auf nem Formular nen Thread. Wenn dieser Startet, also wenn ich nen Button drücke, dann wird bis 75 durchgezählt. Fortschritt wird durch ne Progressbar + listbox angezeigt. Hier besteht nun das Problem. Solange der Vorgang durchgeführt wird, hängt die Oberflaäche, sprich, es steht keine Rückmeldung wenn ich die Form beispielsweise Verschieben will.
| Code: | private void button1_Click(object sender, EventArgs e)
{
Thread AufgabeThread = new Thread(Aufgabe);
AufgabeThread.Start();
}
public void Aufgabe()
{
if (listBox1.InvokeRequired)
{
listBox1.Invoke(new MethodInvoker(FuereAufgabeDurch)); //Ich vermute mal hier liegt das Problem, da ich den Hauptthread benutze
}
}
private void FuereAufgabeDurch()
{
for (int index = 0; index < 75; index++)
{
//Do Something
listBox1.Items.Add(string.Format("Status: {0}", index));
progressBar1.Value = index + 1;
Thread.Sleep(Random.BelibiegeZahlBeiMax1000());
Refresh();
}
}
|
Ich hoffe, ihr könnt mir da weiterhelfen.
Falls irgendwas net klar sein sollte, dann fragt einfach mal nach!
Danke im Voraus.
MfG |
|
| Nach oben |
|

|
upsj Member
Anmeldedatum: 04.02.2010 Beiträge: 60
|
Verfasst am: 03.05.2010, 21:04 Titel: |
|
Aus MSDN:
| Zitat: | ListBox.Invoke-Methode
Führt einen Delegaten in dem Thread aus, der das dem Steuerelement zugrunde liegende Fensterhandle besitzt. |
Die Funktion wird also im Haupthread ausgeführt. warum nicht einfach so?
| Code: | public void Aufgabe()
{
FuereAufgabeDurch();
} |
Andere Möglichkeit: Vor Thread.Sleep() noch Application.DoEvents() einfügen _________________ No keyboard found... Press any key to continue |
|
| Nach oben |
|

|
firefox1988 Member
Anmeldedatum: 08.08.2007 Beiträge: 20
|
Verfasst am: 03.05.2010, 21:09 Titel: |
|
@upsj: Danke für deine Antwort.
So einfach kann ich es leider net ausführen(den Code, den du vorgeschlagen hast). Im Moment kann ich nur durch den Hauptthread auf lisbox zugreifen, daher die Invoke Methode.
Application.DoEvents() Funktioniert zwar, aber ich wollte es nur mit (Arbeits-)Threads lösen. |
|
| Nach oben |
|

|
upsj Member
Anmeldedatum: 04.02.2010 Beiträge: 60
|
Verfasst am: 03.05.2010, 22:02 Titel: |
|
vielleicht hilft dir das hier weiter: http://www.tech-recipes.com/rx/1915....les_to_a_new_thread_in_c/
soweit ich das verstehe, müsstest du nur den Thread-Aufruf etwas verändern, indem du nicht einfach die Funktion übergibst, sondern ein ThreadStart-Delegate. Da die aufgerufene Funktion (vermutlich) auch in der Form-Klasse liegt, müsste diese dann auf die enthaltenen Variablen zugreifen können. _________________ No keyboard found... Press any key to continue |
|
| Nach oben |
|

|
SilentWarrior Member
Anmeldedatum: 22.06.2008 Beiträge: 782 Wohnort: Lübeck
|
|
| Nach oben |
|

|
firefox1988 Member
Anmeldedatum: 08.08.2007 Beiträge: 20
|
Verfasst am: 04.05.2010, 19:40 Titel: |
|
Danke für eure Hilfe, hat bestens geklappt!
Jetzt wollte ich nen Schritt weitergehen und das ganze mit Patterns machen. Am besten Command Patterns.
Hab die Commands geschrieben, doch hier das gleiche Problem, es wird der Hauptthread gestartet dadurch friert das UI ein.
Interface fuer mein Command:
| Code: | using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Start
{
public interface ICommand
{
string index { get; set; }
void Execute(string index);
}
}
|
Das Command selbst:
| Code: | using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Start
{
public abstract class Command : ICommand
{
public string index { get; set; }
public abstract void Execute(string indexer);
}
}
|
Mein Executer:
| Code: | using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Start
{
public class Executor
{
public void ExecuteCommand(ICommand commandInterface)
{
commandInterface.Execute(null);
}
}
}
|
Hier die Ausfuehrung des Commands:
| Code: | using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Start.CommandPatterns
{
public class AufgabenCommand : Command
{
public override void Execute(string indexer)
{
index = indexer;
}
}
} |
Das Hauptformular:
| Code: |
private Executor executor;
public delegate void AktuellerEintrag(string index);
private void ListboxEintragHinzufuegen(string text)
{
if (InvokeRequired)
{
Invoke(new AktuellerEintrag(ListboxEintragHinzufuegen), new object[] {text});
}
else
listBox1.Items.Add(text);
Refresh();
}
public Form1()
{
InitializeComponent();
executor = new Executor();
}
private void button1_Click(object sender, EventArgs e)
{
AufgabenCommand aufgabenCommand = new AufgabenCommand();
executor.ExecuteCommand(aufgabenCommand);
for (int i = 0; i < 100; i++)
{
aufgabenCommand.Execute(i.ToString());
Thread.Sleep(Random.ZufallszahlZwischenNullUndTausend());
string text = string.Format("Status : {0}", i);
ListboxEintragHinzufuegen(text);
}
}
|
Wie gesagt, wenn das so ausgeführt wird, dann ist mein altes Problem mit dem einfrieren der GUI wieder da!
Ich mache da irgendwas falsch. Ich hoffe, ihr könnt mir da weiterhelfen.
Mfg |
|
| Nach oben |
|

|
Wasabi Member
Anmeldedatum: 02.10.2009 Beiträge: 280
|
Verfasst am: 04.05.2010, 19:55 Titel: |
|
So als Frage Was macht das "Refresh()" und soll das wirklich bei jedem ListboxEintragHinzufuegen ausgeführt werden? _________________ Wer mehr gibt bekommt mehr zurück.
-------------------------------------------
Jay, ich habe endlich auch eine Seite die ich in die Signatur tun kann:
Rezentinox Team |
|
| Nach oben |
|

|
firefox1988 Member
Anmeldedatum: 08.08.2007 Beiträge: 20
|
Verfasst am: 04.05.2010, 19:59 Titel: |
|
| Wasabi hat Folgendes geschrieben: | | So als Frage Was macht das "Refresh()" und soll das wirklich bei jedem ListboxEintragHinzufuegen ausgeführt werden? |
Das Aktualisiert die Einträge in der ListBox. Ansonsten friert das Programm einfach nur ein und nachdem alles fertig ist, wird die Aufzählung in der Listbox angezeigt. |
|
| Nach oben |
|

|
Wasabi Member
Anmeldedatum: 02.10.2009 Beiträge: 280
|
Verfasst am: 04.05.2010, 20:15 Titel: |
|
Hast du mal debuggt an welcher stelle er einfriert? _________________ Wer mehr gibt bekommt mehr zurück.
-------------------------------------------
Jay, ich habe endlich auch eine Seite die ich in die Signatur tun kann:
Rezentinox Team |
|
| Nach oben |
|

|
firefox1988 Member
Anmeldedatum: 08.08.2007 Beiträge: 20
|
Verfasst am: 04.05.2010, 20:22 Titel: |
|
| @Wasabi: Nicht das Programm selbst friert ein, sondern die Oberfläche. War unglücklich von mir formuliert. |
|
| Nach oben |
|

|
Wasabi Member
Anmeldedatum: 02.10.2009 Beiträge: 280
|
Verfasst am: 04.05.2010, 20:25 Titel: |
|
Nein Nein ich wusste schon was du meinst aber an welcher stelle friert das GUI ein das meinte ich. Also nach welcher Aktion genau Notfalls kannst du in den Projekt Optionen mal auf Console Anwendung umstellen und ausgaben über die Console laufen lassen. _________________ Wer mehr gibt bekommt mehr zurück.
-------------------------------------------
Jay, ich habe endlich auch eine Seite die ich in die Signatur tun kann:
Rezentinox Team |
|
| Nach oben |
|

|
firefox1988 Member
Anmeldedatum: 08.08.2007 Beiträge: 20
|
Verfasst am: 04.05.2010, 20:31 Titel: |
|
| Sobald der Hauptthread gestartet wird, hängt sich das GUI auf. |
|
| Nach oben |
|

|
Wasabi Member
Anmeldedatum: 02.10.2009 Beiträge: 280
|
Verfasst am: 04.05.2010, 20:42 Titel: |
|
hmm direkt nach dem Start also nicht erst wenn du den Button drückst weil da hast du eine recht großen sleep Zahlenbereich.
Ansonsten startest du sonst nirgendwo ein sleep oder irgendeine schleife? _________________ Wer mehr gibt bekommt mehr zurück.
-------------------------------------------
Jay, ich habe endlich auch eine Seite die ich in die Signatur tun kann:
Rezentinox Team |
|
| Nach oben |
|

|
firefox1988 Member
Anmeldedatum: 08.08.2007 Beiträge: 20
|
Verfasst am: 04.05.2010, 20:51 Titel: |
|
Ich meinte auch beim Button Klick, wo ich den Hauptthread verwende. Mit der Schleife hat es herzlich wenig zu tun, denn mit den Areitsthreads hat ja alles geklappt. Jetzt möchte ich das ganze mit meinen Command Patterns machen.
Danke für deine Hilfe bis hierher. |
|
| Nach oben |
|

|
Wasabi Member
Anmeldedatum: 02.10.2009 Beiträge: 280
|
Verfasst am: 04.05.2010, 21:11 Titel: |
|
| Zitat: | | Thread.Sleep(Random.ZufallszahlZwischenNullUndTausend()); |
Thread Bezieht sich auf das thread in dem es ausgeführt wird und in dem falle das Hauptthread wenn ich mich nicht täusche
und da du die schleife schon alleine 100 mal durchlaufen lässt kannst du auf einen wert bis zu 100 000 ms sleep zeit kommen. _________________ Wer mehr gibt bekommt mehr zurück.
-------------------------------------------
Jay, ich habe endlich auch eine Seite die ich in die Signatur tun kann:
Rezentinox Team |
|
| Nach oben |
|

|
|