2009-03-02 5 views
1

Ich möchte einen Hintergrundthread zum Laden der XML-Daten verwenden, möglicherweise mit einem Fortschrittsbalken, um den Benutzer wissen zu lassen, dass die Anwendung aktiv etwas tut. Ich habe diesen Code durch die Suche im Internet geschrieben.
Ich möchte eine XML-Struktur in Treeview auf Winform laden, wenn ein Benutzer eine Schaltfläche Durchsuchen klickt. Im Falle einer großen XML-Datei friert die Winform ein. Damit der Benutzer wissen kann, dass im Hintergrund die Arbeit läuft, möchte ich eine Fortschrittsanzeige hinzufügen. Ich habe hier einen Hintergrund-Arbeiter benutzt.Fortschrittsbalken beim Hochladen der Xml-Datei

Aber es hebt eine Ausnahme von System.ArgumentException zeigt diese Meldung: auf XmlDocument.Load (txtFileName.Text); "Die URL darf nicht leer sein \ r \ nParameter Name url." diese Linie.
Meine XML-Datei ist im richtigen Format und ist an der richtigen Stelle, wo ich ausgewählt habe. Aber ich bin nicht in der Lage, die Ursache für diese Ausnahme zu finden. Können Sie mir bitte helfen oder mir die Korrektur in meinem Code mitteilen?
Danke ....

 private void btnBrowse_Click(object sender,EventArgs e) 
     { 
      bgWorker1.RunWorkerAsync(); 
      StripProgressBar.Value = 0; 
      toolStripStatusLabel1.Text = "Browsing for a Xml file"; 

      if (open.ShowDialog(this) == DialogResult.OK) 
      { 
       txtFileName.Text = open.FileName; 
       initiatingTree(open.FileName); //this variable gives the name of selected file 
      } 
      while (this.bgWorker1.IsBusy) 
      { 
       StripProgressBar.Increment(1); 
       // Keep UI messages moving, so the form remains 
       // responsive during the asynchronous operation. 
       Application.DoEvents(); 
      } 
     }//Browse button  
     private void bgWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      xmlDocument = new XmlDocument(); 
      Thread.Sleep(5000); 
      xmlDocument.Load(txtFileName.Text); 
      btnBrowse.Enabled = false; 
     } 
     private void bgworker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      // Set progress bar to 100% in case it's not already there. 
      StripProgressBar.Value = 100; 
      if (e.Error == null) 
      { 
       MessageBox.Show(xmlDocument.InnerXml, "Download Complete"); 
      } 
      else 
      { 
       MessageBox.Show("Failed to download file"); 
      } 
      // Enable the Browse button and reset the progress bar. 
      this.btnBrowse.Enabled = true; 
      StripProgressBar.Value = 0; 
      toolStripStatusLabel1.Text = "work finished processing request."; 
     }//workerCompleted 

Antwort

4

Sie sofort den asynchronen Prozess beginnt, wenn der Benutzer auf „Durchsuchen“ klickt, von

bgWorker1.RunWorkerAsync(); 

Dies ruft die DoWork Methode Ihrer Hintergrund Arbeiter nennen, die schläft für 5 Sekunden und zieht den Wert von txtFileName.Text, ob der Benutzer seine Eingabe in der FileOpenDialog abgeschlossen hat oder nicht.

Sie wären besser dran, die byWorker1.RunWorkerAsync() (und die busy Warte) in den if (open.ShowDialog(this) == DialogResult.OK) Block zu bewegen.

private void btnBrowse_Click(object sender,EventArgs e) 
    { 
     StripProgressBar.Value = 0; 
     toolStripStatusLabel1.Text = "Browsing for a Xml file"; 

     if (open.ShowDialog(this) == DialogResult.OK) 
     { 
      txtFileName.Text = open.FileName; 
      initiatingTree(open.FileName); 

      bgWorker1.RunWorkerAsync(); 

      while (this.bgWorker1.IsBusy) 
      { 
       StripProgressBar.Increment(1); 
       // Keep UI messages moving, so the form remains 
       // responsive during the asynchronous operation. 
       Application.DoEvents(); 
      } 
     } 
    } 

Für diese Art von Problemen, kann es hilfreich sein, einen Haltepunkt in Ordnung zu bringen, wo die Datei geladen werden wird, und sieht, was der Wert ist, wenn das passiert ... Sie vielleicht feststellen, dass es immer genannt mit einer leeren Zeichenfolge.

Sie könnten auch die Version von RunWorkerAsync betrachten, die einen Parameter annimmt; Sie könnten die Datei auf diese Weise übergeben, anstatt sie asynchron aus dem Textfeld zu lesen.

Und persönlich würde ich keine Schleife verwenden, die Application.DoEvents() ruft; Stattdessen würde ich die Kontrolle zurück auf den UI-Thread und dann Invoke() darauf aus dem asynchronen Thread zurückgeben, um die Fortschrittsbalken-Updates zu bewirken.

+0

danke, Noch bleibt die Ausnahme. Bitte beachten Sie die Ausnahme, was ich in meiner Frage gestellt habe. –

1

Wenn die Methode bgWorker1.RunWorkerAsync(); heißt das Ereignis DoWork wird gefeuert.

Da die Methode am Anfang der Anwendung aufgerufen wird, ist das Textfeld Dateiname leer.

Ich hoffe, Sie haben es verstanden.