Hallo ihr Lieben,
ich möchte von euch kurz wissen, ob meine Einschätzung korrekt ist.
Zur zu erledigenden Aufgabe: Ein Thread liest eine größere CSV-Datei ein und verarbeitet diese. Dies wird am Anfang der Applikation ausgeführt, da der Vorgang ca. 2 Sekunden dauert und sowieso einige Forms durchgeklickt werden müssen.
Der Code der aufgerufenen Methode des Singletonobjekts:
public void CreateNewDocIDTable()
{
_docIdTable = null;
if (bw != null && bw.IsBusy)
{
bw.CancelAsync();
while (bw.IsBusy)
{
Thread.Sleep(50);
}
}
try
{
bw.RunWorkerAsync();
}
catch (Exception ex)
{
string s = ex.Message;
}
}
Die Initialisierung des BackgroundWorkers:
bw = new System.ComponentModel.BackgroundWorker();
bw.DoWork += new System.ComponentModel.DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
Das Abholen des erstellten Objekts:
public Table DocIdTable
{
get
{
return _docIdTable;
}
set
{
_docIdTable = value;
}
}
Nun muss ich also sicherstellen, dass das Objekt bereits erstellt ist, wenn es abgerufen wird. Auf den Thread warten (if (_docIdTable == null) Thread.Sleep(xxx)) ist unschön und funktioniert auch nicht: Die bw_RunWorkerCompleted-Methode wird nicht mehr aufgerufen.
Rein fachlich wäre ein Warten auf den Thread bei dieser Applikation sogar i.O., einen praktikablen Weg sehe ich aber nicht.
Benötige ich hier das Observer-Muster?
Danke,
Liebe Grüße,
yamukud
Nun muss ich also sicherstellen, dass das Objekt bereits erstellt ist, wenn es abgerufen wird.
Baue deine Anwendung lieber so um, dass der Abruf erst aufgrund von RunWorkerCompleted erfolgt (indem die Form z.B. erst dort geöffnet wird).
Thread.Sleep deutet in 99% der Fälle auf eine sehr suboptimale Lösung hin.
Hallo Winsharp,
würde ich es aus der RunWorkerCompleted-Methode heraus erlauben, die nächste Form aufzurufen, hätte ich keinen Vorteil dazu, die CSV-Datei erst bei Arbeitsbeginn zu laden. Nur der Ort des Wartens hat sich verschoben.
Und wie beschrieben funktioniert Thread.Sleep sowieso nicht (RunWorkerCompleted-Methode wird nach dem Durchlaufen der DoWork-Methode nicht aufgerufen).
Liebe Grüße,
yamukud
Nachtrag: Meine einzige Idee wäre eben den Arbeitsbeginn zu blockieren, bis ein Event ankommt, dass das Objekt geladen wurde. Es verursacht aber eine unschöne Architektur, das Singletonobjekt soll "stand-alone" funktionieren.
Hallo yamukud,
im GUI-Thread darfst du nicht warten, siehe [FAQ] Warum blockiert mein GUI?
Du musst also die Aktion, die die Daten verarbeiten soll, erstmal abbrechen, wenn die Daten noch nicht vorhanden sind und sie später wieder neu starten, z.B. per Timer oder noch besser im RunWorkerCompleted, das auch eintreffen sollte, wenn das GUI nicht blockiert ist.
herbivore
Hallo herbivore,
schön wieder von dir zu lesen.
Abbrechen und neu starten ist auch keine Option, weil ich dann keinen Benefit habe.
Ich warte nicht in der GUI, sondern im Singletonobjekt.
Liebe Grüße,
yamukud
würde ich es aus der RunWorkerCompleted-Methode heraus erlauben, die nächste Form aufzurufen, hätte ich keinen Vorteil dazu, die CSV-Datei erst bei Arbeitsbeginn zu laden.
Das war ja auch nur ein Beispiel - du sollst einfach das, was du "nach dem Warten" machen willst, in RunWorkerCompleted machen.
Hallo yamukud,
Abbrechen und an dem Punkt, an dem abgebrochen wurde, neu zu starten, ist das beste was geht!
Und es ist auf jedenfalls besser, als alles rein sequentiell zu machen. Durch Abbrechen und Neustarten wird ja nur die Restzeit der langlaufenden Aktion "gewartet" statt die gesamt Zeit der langlaufenden Aktion wie beim rein sequentiellen Vorgehen.
herbivore