2009-03-02 14 views
1

Je souhaite utiliser un thread d'arrière-plan pour le chargement des données XML, éventuellement avec une barre de progression pour indiquer à l'utilisateur que l'application est en train de faire quelque chose. J'ai écrit ce code en cherchant sur Internet.
Je veux charger une arborescence XML dans treeview sur winform lorsqu'un utilisateur clique sur un bouton Parcourir. Dans le cas d'un fichier XML volumineux, le winform se bloque. Pour que l'utilisateur sache qu'en arrière-plan le travail se déroule, je souhaite ajouter une barre de progression. J'ai utilisé un worker de fond ici.Barre de progression lors du chargement de fichier XML

Mais il soulève une exception System.ArgumentException montrant ce message: le XmlDocument.Load (txtFileName.Text); "L'URL ne peut pas être vide \ r \ nom nParameter url." cette ligne.
Mon fichier xml est au format correct et se trouve au bon endroit où j'ai choisi. Mais je suis incapable de trouver la cause de cette exception. Pouvez-vous s'il vous plaît aider ou me dire la correction dans mon code?
Merci ....

 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 

Répondre

4

Vous commencez le processus asynchrone immédiatement lorsque l'utilisateur clique sur « Parcourir », en appelant

bgWorker1.RunWorkerAsync(); 

Ce appelle la méthode DoWork de votre travailleur de fond, qui dort pendant 5 secondes, et tire la valeur de txtFileName.Text si l'utilisateur a terminé ou non leur entrée dans le FileOpenDialog.

Vous feriez mieux de déplacer le byWorker1.RunWorkerAsync() (et l'attente occupée) dans le bloc if (open.ShowDialog(this) == DialogResult.OK).

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(); 
      } 
     } 
    } 

Pour ce genre de problèmes, il peut être utile de mettre un point d'arrêt à droite où le fichier va se charger, et voir ce que la valeur est quand cela arrive ... vous remarquerez peut-être que ça s'appelle avec une chaîne vide.

Vous pouvez également considérer la version de RunWorkerAsync qui prend un paramètre; vous pouvez passer le fichier de cette façon, au lieu d'essayer de le lire de manière asynchrone à partir de la zone de texte.

Et personnellement, je n'utiliserais pas une boucle qui appelle Application.DoEvents(); Au lieu de cela, je retournerais le contrôle au thread de l'interface utilisateur, puis Invoke() à partir du thread asynchrone pour effectuer les mises à jour de la barre de progression.

+0

merci, Encore l'exception reste.Veuillez voir l'exception ce que j'ai mis en place dans ma question. –

1

Lorsque la méthode bgWorker1.RunWorkerAsync(); est appelé l'événement DoWork est renvoyé. Comme la méthode est appelée au début de l'application, la zone de texte Nom de fichier est vide.

J'espère que vous avez compris.