none
Laufender Prozess blockiert die Anzeige in einem Label RRS feed

  • Frage

  • Hallo Forum,
    1. Der Programmablauf: ich trenne und anschliessend verbinde ein Netzlaufwerk (Frank Dzaebel: erneut vielen Dank für den Klasse-Hinweis: http://www.codeproject.com/KB/system/mapnetdrive.aspx#_comments ). Dann kopiere ich von dem Netzlaufwerk einge Setupdatein (hmm, ca. 800MB, es dauert eine Weile..). Der Prozess funktioniert einwandfrei. Da aber der der Kopiervorgang ca. 2 Min. dauert möchte ich dem User einen Hinweis in ein Label-Feld anzeigen ("Daten werden kopiert usw...). Offensichtlich blockiert aber entweder der Mappingprozess (ein Widnows-API Zugriff) oder der Kopiervorgang die Anwendung so, das diese Label-Meldung nicht erscheint - nur am Ende des Prozesses ("Kopiervorgang beendet"). Hmm, geht es den gleichen Thread - leider bin ich erst am Anfang von dem langen, wunderbaren C#-Weg und blicke das noch nicht ganz durch...
    Der Code:
         inst.LWTrennen();
                inst.LWMappen();
                if (versionnr.ToString() != String.Empty)
                {
      //hier die Anzeige einblenden..               
      lblAnzeigeInformation.Text = "Die Installationsdaten werden vom Server ins Installverzeichnis kopiert...";

                    switch (versionnr)
                    {
                        case ("2005SE32"):
                            dirCopySource = "H:\\2005\\Mssql_2005_Englisch_32_bit\\Standard_Edition";
                            break;
                        case ("2005EE32"):
                            dirCopySource = "H:\\2005\\Mssql_2005_Englisch_32_bit\\Enterprise_Edition";
                            break;
                        case ("2005SE64"):
                            dirCopySource = "H:\\2005\\MSSQL_2005_English_64_Bit\\Standard_Edition";
                            break;
                        case ("2005EE64"):
                            dirCopySource = "H:\\2005\\MSSQL_2005_English_64_Bit\\Enterprise_Edition";
                            break;
                        default:
                           
                            break;
                    }


                    inst.CopyDirectoryWithIncludedFiles(dirCopySource, dirCopyTarget);
      // Kopieren fertig..Info einblenden
                    lblAnzeigeInformation.Text = "Kopiervorgang erfolgreich abgeschlossen...";
                }

    Danke für Euere Hilfe

    Donnerstag, 17. Februar 2011 11:06

Antworten

  • hi,

    abgesehen davon, das dein switch() Potential für Optimierung bietet - ein Dictionary aus einer Konfigurationsdatei - führe das Kopieren in einem Thread aus, z.B. Ein BackgroundworkerThread:

    http://msdn.microsoft.com/en-us/library/8xs8549b.aspx


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Donnerstag, 17. Februar 2011 11:30
  • Hallo,

    ich entnehme Deiner Beschreibung, dass Du diese ganzen Aktionen im UI Thread durchführst. Solange Du diesen aber mit irgendwelchen Aktionen belegst, kann natürlich nichts anderes gemacht werden.

    Der UI Thread ist dazu zuständig, ständig in einer Schleife eine sogenannte Message Queue nach Ereignissen abzufragen und diese dann auszuwerten. Solche Ereignisse sind z.B. ein Kopfdruck aber auch Nachrichte wie "Label neu malen".

    Die korrekte Lösung aus meiner Sicht wäre z.B., die länger dauernde Aktion in einen BackgroundWorker zu verlagern und dann die Veränderung des Labels über ReportProgres vorzunehmen.

    Die funktionierende, aber aus meiner Sicht zumindest unschöne Lösung könnte sein, nach dem setzen des Labels ein Application.DoEvents(); einzufügen. Hier musst Du aber gut aufpassen, denn es kann dann einiges schieflaufen:

    - Du führst die aktion oben z.B. in einem Button event aus.
    - Du klickst den Button aber zwei Mal! Der zweite Buttonclick wird dann während eined Application.DoEvents() ausgeführt und das kann dann negative Ergebnisse mit sich bringen!

    Der BackgroundWorker ist auf der MSDN Library sehr gut und mit Beispielen dokumentiert.

    Mit den besten Grüßen,

    Konrad

    Donnerstag, 17. Februar 2011 11:37
  • Hallo,

    Du kannst die ReportProgress(int progressPersent, object userState) Methode nutzen. Dann kannst Du ein beliebiges Objekt übergeben (z.B. den String für Dein Label).

    Das ProgressChanged Event bekommt als Parameter ein ProgressChangedEventArgs und dies enthält die Referenz auf das object in der Property UserState.

    Somit wird in etwa bei der Verarbeitung des Events Folgendes möglich:

    lblAnzeigeInformation.Text = (string) e.UserState;

    Mit den besten Grüßen,

    Konrad

    Donnerstag, 17. Februar 2011 13:00
  • hi,

    das hängt davon ab, ob deine Methode CopyDirectoryWithIncludedFiles einen Fortschritt ermitteln kann. Wenn ja, musst du diese Werte übergeben.


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Donnerstag, 17. Februar 2011 13:11

Alle Antworten

  • hi,

    abgesehen davon, das dein switch() Potential für Optimierung bietet - ein Dictionary aus einer Konfigurationsdatei - führe das Kopieren in einem Thread aus, z.B. Ein BackgroundworkerThread:

    http://msdn.microsoft.com/en-us/library/8xs8549b.aspx


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Donnerstag, 17. Februar 2011 11:30
  • Hallo,

    ich entnehme Deiner Beschreibung, dass Du diese ganzen Aktionen im UI Thread durchführst. Solange Du diesen aber mit irgendwelchen Aktionen belegst, kann natürlich nichts anderes gemacht werden.

    Der UI Thread ist dazu zuständig, ständig in einer Schleife eine sogenannte Message Queue nach Ereignissen abzufragen und diese dann auszuwerten. Solche Ereignisse sind z.B. ein Kopfdruck aber auch Nachrichte wie "Label neu malen".

    Die korrekte Lösung aus meiner Sicht wäre z.B., die länger dauernde Aktion in einen BackgroundWorker zu verlagern und dann die Veränderung des Labels über ReportProgres vorzunehmen.

    Die funktionierende, aber aus meiner Sicht zumindest unschöne Lösung könnte sein, nach dem setzen des Labels ein Application.DoEvents(); einzufügen. Hier musst Du aber gut aufpassen, denn es kann dann einiges schieflaufen:

    - Du führst die aktion oben z.B. in einem Button event aus.
    - Du klickst den Button aber zwei Mal! Der zweite Buttonclick wird dann während eined Application.DoEvents() ausgeführt und das kann dann negative Ergebnisse mit sich bringen!

    Der BackgroundWorker ist auf der MSDN Library sehr gut und mit Beispielen dokumentiert.

    Mit den besten Grüßen,

    Konrad

    Donnerstag, 17. Februar 2011 11:37
  • Hallo Stefan, hallo Konrad,
    @Stefan: ich werde das switch-Statement nachbearbeiten, danke für den Hinweis
    Ich versuche jetzt den BackGroundWorker in Zusammenarbeit mit ProgressBar zu implementieren (http://dotnetperls.com/progressbar). Ein sehr gutes Beispiel, aber was übergebe ich dem ReporProgress() wenn bei mir der Prozess keine Zahlen addiert (wie im u. g. Beispiel), sonder Dateien kopiert?
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
          for (int i = 1; i <= 100; i++)
          {
            // Wait 100 milliseconds.
            Thread.Sleep(100);
            // Report progress.
            backgroundWorker1.ReportProgress(i);
          }
        }
    
    
    
    Donnerstag, 17. Februar 2011 12:24
  • Hallo,

    Du kannst die ReportProgress(int progressPersent, object userState) Methode nutzen. Dann kannst Du ein beliebiges Objekt übergeben (z.B. den String für Dein Label).

    Das ProgressChanged Event bekommt als Parameter ein ProgressChangedEventArgs und dies enthält die Referenz auf das object in der Property UserState.

    Somit wird in etwa bei der Verarbeitung des Events Folgendes möglich:

    lblAnzeigeInformation.Text = (string) e.UserState;

    Mit den besten Grüßen,

    Konrad

    Donnerstag, 17. Februar 2011 13:00
  • hi,

    das hängt davon ab, ob deine Methode CopyDirectoryWithIncludedFiles einen Fortschritt ermitteln kann. Wenn ja, musst du diese Werte übergeben.


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Donnerstag, 17. Februar 2011 13:11