2009-03-02 7 views
1

Я хочу использовать фоновый поток для процесса загрузки XML-данных, возможно, с индикатором выполнения, чтобы пользователь знал, что приложение активно что-то делает. Я написал этот код через поиск в сети.
Я хочу загрузить дерево XML в treeview на winform, когда пользователь кликнет кнопкой «Обзор». В случае большого файла XML winform freezes.So, чтобы сообщить пользователю, что в фоновом режиме работа продолжается, я хочу добавить индикатор прогресса. Я использовал фонового работника здесь.Индикатор выполнения при загрузке Xml-файла

Но это поднимает исключение System.ArgumentException показывая это сообщение: на xmlDocument.Load (txtFileName.Text); "URL-адрес не может быть пустым \ г \ nParameter имя URL." этот линия.
Мой XML-файл находится в правильном формате и находится в правильном месте, где я выбрал. Но я не могу найти причину этого исключения. Не могли бы вы помочь или сказать мне исправление в моем коде?
Спасибо ....

 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 

ответ

4

Вы сразу же начинаете асинхронный процесс, когда пользователь нажимает кнопку «Обзор», позвонив по телефону

bgWorker1.RunWorkerAsync(); 

Это вызывает DoWork метода фонового работника, который спит в течение 5 секунд и вытягивает значение от txtFileName.Text независимо от того, завершил ли пользователь свою запись в FileOpenDialog.

Вам будет лучше перемещать byWorker1.RunWorkerAsync() (и ожидание) в блок 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(); 
      } 
     } 
    } 

Для такого рода проблем, это может быть полезно, чтобы поставить точку останова прямо там, где файл собирается загружаться, и посмотреть, что значение, когда это произойдет ... Вы могли бы заметить, что это вызывался с пустой строкой.

Вы также можете рассмотреть версию RunWorkerAsync, которая принимает параметр; вы можете передать файл таким образом, вместо того, чтобы пытаться прочитать его асинхронно из текстового поля.

И лично я не использовал бы цикл, который вызывает Application.DoEvents(); вместо этого я вернул бы управление обратно в поток пользовательского интерфейса, а затем Invoke() на него из асинхронного потока для обновления обновлений progressbar.

+0

спасибо, Все еще исключение остается. Пожалуйста, обратите внимание на исключение, которое я поставил в своем вопросе. –

1

При использовании метода bgWorker1.RunWorkerAsync(); называется событием DoWork.

Поскольку метод вызывается в начале приложения, текстовое поле имени файла пуст.

Надеюсь, вы поняли.

Смежные вопросы