Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Erstellen eines reinen Wartedialogs in einem anderen Thread
lukasS
myCSharp.de - Member

Avatar #avatar-3121.jpg


Dabei seit:
Beiträge: 65
Herkunft: Herne

Themenstarter:

Erstellen eines reinen Wartedialogs in einem anderen Thread

beantworten | zitieren | melden

Hallo,

ich habe einen Wartedialog erstellt. Dieser wird aufgerufen, wenn ich z. B. nach bestimmten Dateien in einem Ordner scanne und/oder noch andere Sachen im Hauptdialog beim Startvorgang passieren.

Was ich mache ist, ich scanne Ordner im Haupt-Thread.
Dabei rufe ich eine static-Funktion startWaitingForm.
Diese Funktion erstellt mir einen neuen Thread in dem der Wartedialog laufen soll.


      private static frmWaiting frmWait;
      private static Thread thWait;

      public static void startWaitingForm()
      {
         if (thWait != null)
         {
            if (thWait.IsAlive)
               thWait.Abort();
         }

         thWait = new Thread((ShowWaitDialog));
         thWait.Start();

      }

      private static void ShowWaitDialog()
      {
         frmWait = new frmWaiting();
         frmWait.ShowDialog();
      }

Während des Scan-Vorgangs rufe ich die static-Funktion updateWaitingForm, die einen Wert als Parameter hat, auf. Dieser Wert soll in dem Warte-Dialog angezeigt werden.


      public static bool updateWaitingForm(string sTitle, string sPath)
      {
         if (frmWait == null)
            return true;

         if (frmWaiting.bCancel)
            return false;

         if (frmWait.InvokeRequired)
         {
            updateWaitForm callback = new updateWaitForm(updateWaitingForm);
            frmWait.Invoke(callback, new object[] { sTitle, sPath });
         }
         else
         {
            frmWait.updateWaitingForm(sTitle, sPath);
         }

         return true;
      }

Nach dem Scan-Vorgang rufe ich zum Schluss die closeWaitingForm auf. Diese soll den Dialog und Thread schließen.


      public static void closeWaitingForm()
      {
         if (frmWait == null)
            return;

         if (frmWait.InvokeRequired)
         {
            closeWaitForm callback = new closeWaitForm(closeWaitingForm);
            frmWait.Invoke(callback);
            thWait.Abort();
         }
         else
         {
            frmWait.Close();
         }
      }

Im Normalfall würde man den Scan-Vorgang in einen anderen Thread verlegen, allerdings möchte ich nur den Warte-Dialog in einem anderen Thread habe und nur den Text ändern lassen. Es passieren nämlich noch einige Sachen später in dem Hauptdialog (Bäume werden aufgebaut, Tabellen gefüllt etc.). Dabei soll der Dialog halt offen bleiben.

Der ganze Vorgang funktioniert, allerdings wenn sich keine und sehr wenige Datei in dem Ordner befinden, kommt wohl das Schließen zu schnell oder ähnliches und es kommt zu einem Absturz oder manchmal schließt sich der Warte-Dialog nicht. Wenn ich das langsam im Debugger durchlaufe, läuft alles.
Ich sehe leider den Wald vor lauter Bäumen nicht mehr. Ich habe schon so viel damit herum experimentiert, leider alles ohne ERfolg. Leider konnte ich noch kein Beispiel finden, wo der Wartedialog-Text einfach so geändert wird vom Haupt-Thread.

Ich weiß jetzt nicht ob mein Ansatz so weit richtig ist, deshalb frage ich halt hier
Gerne tue ich noch die paar Zeilen Code vom Dialog rein, wenn notwendig.

Was genau mache ich falsch ?(

Danke schon mal!!!

Lukas
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.975

beantworten | zitieren | melden

Zitat
Ich sehe leider den Wald vor lauter Bäumen nicht mehr. Ich habe schon so viel damit herum experimentiert, leider alles ohne ERfolg
Zitat
Ich weiß jetzt nicht ob mein Ansatz so weit richtig ist
Nein, dein Ansatz ist komplett falsch.

Die UI wid immer im Hauptthread verwaltet, die Aktion musst du in einem Extra Thread durchführen.
"Bitte warten"-Fenster anzeigen während Daten geladen werden
private Nachricht | Beiträge des Benutzers
felix
myCSharp.de - Member



Dabei seit:
Beiträge: 174

beantworten | zitieren | melden

Sehe ich das falsch, oder hast du mit deiner Implementierung der Funktion "updateWaitingForm" eine Endlos-Schleife produziert? Aus meiner Sicht tut die nämlich gar nichts, ausser sich die ganze Zeit selber wieder aufzurufen.
private Nachricht | Beiträge des Benutzers
lukasS
myCSharp.de - Member

Avatar #avatar-3121.jpg


Dabei seit:
Beiträge: 65
Herkunft: Herne

Themenstarter:

beantworten | zitieren | melden

Hallo zusammen und danke schön erstmal!

Nein, dort ist keien Endlos-Schleife, sonst würde es ja nicht funktioniert wenn mehrere Objekte gescannt werden. Das Invoke ruft zwar die selben Funktion auf, diese wandert dann aber nicht mehr in den IF-Zweig, sondern in das ELSE wo dann die Texte gesetzt werden.

Im Moment baue ich das ganze um. FZelle gab mir den link zu einem anderen Thread wo das Stichwort Splash-Screen auftauchte. Das brachte mich auf Yet Another Splash Screen in C# wo allerdings der selbe Fehler vorkommt, den ich auch habe (Dialog wird geschlossen, während der noch nicht aufgebaut wurde). Aber dennoch bringt mich das erstmal weiter.

Lukas
private Nachricht | Beiträge des Benutzers
felix
myCSharp.de - Member



Dabei seit:
Beiträge: 174

beantworten | zitieren | melden

Ich sehe aber im ELSE-Zweig bisher nur das hier:

frmWait.updateWaitingForm(sTitle, sPath);
Und das ruft eben genau diese Funktion wieder auf, ohne irgendeinen Status zu aktualisieren. Oder ist der Code den du gepostet hast nicht aktuell?
private Nachricht | Beiträge des Benutzers
witte
myCSharp.de - Member



Dabei seit:
Beiträge: 955

beantworten | zitieren | melden

Hi,

warum verwendest du nicht die TPL? Also das Arbeiten mit Tasks, async und await? Dann kannst du das Scannen in einem Task auslagern und die GUI friert nicht ein. Des weiteren könntest du dich mit den Producer/Consumer-Pattern beschäftigen, also eine Akteur schaufelt sich durch die Platte und bietet die Dateiinhalte an während die anderen diese Daten verarbeiten.
private Nachricht | Beiträge des Benutzers
lukasS
myCSharp.de - Member

Avatar #avatar-3121.jpg


Dabei seit:
Beiträge: 65
Herkunft: Herne

Themenstarter:

beantworten | zitieren | melden

Zitat von felix
Ich sehe aber im ELSE-Zweig bisher nur das hier:

frmWait.updateWaitingForm(sTitle, sPath);
Und das ruft eben genau diese Funktion wieder auf, ohne irgendeinen Status zu aktualisieren. Oder ist der Code den du gepostet hast nicht aktuell?

Ach,das hast du gemeint. Der Code ist nicht komplett. Es ist eine Funktion in dem frmWait, die genauso heißt. Die Sachen hier die sind in einer anderen Klasse.
Ich wollte jetzt nicht alles hier reinstellen, weil das zu viel wäre. Aber stimmt, für eine bessere Verdeutlichung hätte ich das zum Teil umschreiben sollen.
private Nachricht | Beiträge des Benutzers
felix
myCSharp.de - Member



Dabei seit:
Beiträge: 174

beantworten | zitieren | melden

Nagut. Du greifst aber zumindest auf die gleiche Instanz zu (immer frmWait). Das bedeutet, dass es eben doch die gleiche Funktion ist. Also entweder ich bin total blind, oder deine eigene Namensgebung ist dir jetzt auf die Füße gefallen.

Würde Möglichkeit 1 aber auch nicht ausschließen :)
private Nachricht | Beiträge des Benutzers
lukasS
myCSharp.de - Member

Avatar #avatar-3121.jpg


Dabei seit:
Beiträge: 65
Herkunft: Herne

Themenstarter:

beantworten | zitieren | melden

Zitat von witte
Hi,

warum verwendest du nicht die TPL? Also das Arbeiten mit Tasks, async und await? Dann kannst du das Scannen in einem Task auslagern und die GUI friert nicht ein. Des weiteren könntest du dich mit den Producer/Consumer-Pattern beschäftigen, also eine Akteur schaufelt sich durch die Platte und bietet die Dateiinhalte an während die anderen diese Daten verarbeiten.

Interessante Idee, danke für den Tipp! Wenn mir bisschen Zeit übrig bleibt, schaue ich es mir mal an.
private Nachricht | Beiträge des Benutzers
steffen_dec
myCSharp.de - Member



Dabei seit:
Beiträge: 322

beantworten | zitieren | melden

Hallo,

vielleicht kannst Du was von einem Splashscreen abschauen, hier ein Beispiel:
http://www.codeproject.com/Articles/5454/A-Pretty-Good-Splash-Screen-in-C

Grüße
Steffen
private Nachricht | Beiträge des Benutzers