Hallo zusammen,
folgendes ist gegeben:
Ein User kann nun in der Form einen Pfad zu einer .txt Datei angeben und mit einem Button-Klick konvertieren lassen (Inhaltlich, ist hier aber irrelevant).
Beim Klick auf den Button wird in meiner FileHandler-Klasse ein Backgroundworker gestartet der die Input-Datei ausliest und entsprechent konvertiert. Nachdem der Backgroundworker fertig ist, soll nun der konvertierte Inhalt in der Form1 scintilla-Box angezeigt werden.
Meine Frage ist nun, wie kann ich meiner Form1 mitteilen, dass der bgworker abgeschlossen ist und der Inhalt nun in der scintilla-Box angezeigt werden soll, ohne die Form via Schleife zu blockieren?
FileHandler.cs - BGworker
public void convertTextFile()
{
bgWorker = new BackgroundWorker();
bgWorker.DoWork += new DoWorkEventHandler(bwDoWorkConvert);
bgWorker.RunWorkerAsync();
}
FileHandler.cs - DoWorkConvert
private void bwDoWorkConvert(object sender, DoWorkEventArgs e)
{
//hier wird der Dateiinhalt konvertiert
}
Schonmal vielen Dank für die Hilfe.
PS: ich habe bisher noch nie mit dem bgworker gearbeitet, bin in dieser Hinsicht also ziemlich unerfahren.
Du musst das Event RunWorkerCompleted des BackgroundWorkers abonnieren und verarbeiten. Das Event wird ausgelöst, wenn (in Deinem Fall) bwDoWorkConvert durchgelaufen ist.
Schau Dir einfach ein Tutorial im Netz dazu an (z. B. das hier)
PS: Den BackgroundWorker nutzt man eigentlich nicht mehr, dafür gibt es heutzutage Tasks.
Hallo hypersurf,
danke schon mal für die Antwort.
Okay, das RunWorkerCompleted-Event wird korrekt getriggert, aber wie sage ich nun meiner Form, dass das Textfeld aktualisiert werden muss?
Na ganz einfach mit Textfeld.Text = "Ein Text";
Na ganz einfach mit
Textfeld.Text = "Ein Text";
Ganz so einfach ist es halt nicht, der bgworker läuft ja in einem Objekt meiner Klasse "FileHandler" und hat daher keinen Zugriff auf das Textfeld der Form.
Hallo Shenzu,
hast du dir mal [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) durchgelesen?
Eleganteste Art aus Worker-Thread auf Controls zugreifen [generell Kontrollfluss zwischen Threads]
Gruss
Coffeebean
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
Hi Coffeebean,
danke auch dir für die Antwort. Ich habe mich ein bisschen eingelesen, ich verstehe leider trotzdem nicht, wie ich das nun zum laufen bekomme.
Wenn ich in folgendem Code versuche via Invoke auf die Textbox zuzugreifen bekomme ich nur Fehler, Invoke ist hier wohl auch nicht verfügbar, muss ich hier irgendwie meinem Worker die GUI mitgeben?
private void bwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if( e.Cancelled)
{
//Cancel
}
else if(e.Error != null)
{
//Error
}
else
{
//Erfolgreich
//do smth
}
}
WPF oder WinForms?
Du hast leider in keinem entsprechenden Forum gepostet.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo,
dem BackgroundWorker
musst Du bestimmt keine GUI bekannt geben.
Die brauchst Du ja auch nur in dem RunWorkerCompleted
-Handler, und der Handler gehört nicht zum BackgroundWorker
, sondern zu einer Deiner eigenen Klassen.
Du hast also 2 Möglichkeiten:
Entweder gibst Du gibst der FileHandler
-Klasse die Form (oder die zu aktualisierenden Controls) mit - das ist die unschöne Variante.
Oder Du verpasst Deiner FileHandler
-Klasse ein eigenes Event, das Du von der Form aus abonnieren kannst - das ist die saubere Variante. Dieses Event feuerst Du dann im RunWorkerCompleted
-Handler. In einer entsprechenden EventArgs
-Klasse gibst Du alle Informationen mit, die die Form kennen muss, um die GUI zu aktualisieren: [FAQ] Eigenen Event definieren / Information zu Events (Ereignis/Ereignisse)
Die Invoke
-Geschichten kannst Du Dir beim BackgroundWorker
normalerweise sparen, weil sie in dem Thread laufen, in dem RunWorkerAsync
aufgerufen wird. Wenn Dein FileHandler nicht schon einen eigenen Thread hat, ist das der GUI-Thread, und Du kannst auf die Controls ohne Invoke
zugreifen.
Gruß, MarsStein
EDIT sagt noch: Wenn Du das eigene Event angehst, und die Informationen für die GUI in der FileHandler
-Klasse als public
Properties vorliegen, kann es auch reichen, in der Form im EventHandler, den sender
auf FileHandler
zurückzucasten und dann auf diese Properties zuzugreifen. Dann sparst Du Dir eine eigene EventArgs
-Klasse. Geschmackssache.
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Hallo MarsStein,
danke für die Antwort.
Ich muss gestehen, ich programmiere nicht so viel und bin daher nicht mit Events, Threads, etc. vertraut. Daher muss ich erstmal verstehen, was diese ganzen Handler, Events. etc. machen.
Ich habe den konvertierten Text tatsächlich als public Property in meiner FileHandler-Klasse vorliegen.
Ich schaue mal, wie weit ich komme.
Danke nochmals an alle für die Beiträge.
Grüße
Shenzu
Ich habe nun in meiner FileHandler-Klasse ein entsprechendes Event erstellt:
public event EventHandler WorkerFinished;
protected virtual void OnWorkerFinished (EventArgs e)
{
EventHandler handler = WorkerFinished;
if(handler != null)
{
handler(this, e);
}
}
Das Event habe ich entsprechend in meiner Form aboniert
private void btnConvert_Click(object sender, EventArgs e)
{
FH.WorkerFinished += FH_WorkerFinished;
FH.convertTextFile();
}
static void FH_WorkerFinished(object sender, EventArgs e)
{
Console.WriteLine("Event ausgelöst!");
}
Ich sehe hier auch die Ausgabe von "Event ausgelöst!" in der Console, allerdings kann ich in FH_WorkerFinished ebenfalls nicht auf meine Form zugreifen !?
Hallo,
warum ist FH_WorkerFinished
denn static
? Das sollte eine Instanzmethode der Form sein, dann kannst Du auch zugreifen 😃
So in der Art:
void FH_WorkerFinished(object sender, EventArgs e)
{
Console.WriteLine("Event ausgelöst!");
var fileHandler = (FileHandler)sender;
myTextField.Text = fileHandler.ConvertedText;
}
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Ich hatte das so von einem MSDN-Artikel abgekupfert.
Vielen vielen Dank, nun hat es schließlich doch noch funktioniert 😃)))))
Ich sehe schon, ich muss mich mehr mit Events und Threads auseinander setzen, da habe ich wohl noch sehr große Defizite.
Danke nochmals allen für die Mithilfe, der Thread darf geschlossen werden 😃