Индикатор выполнения загрузки файла XML - PullRequest
1 голос
/ 02 марта 2009

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

Но возникает исключение System.ArgumentException, показывающее это сообщение «URL не может быть пустым. \ R \ nИмя параметра: url» в xmlDocument.Load (txtFileName.Text); эта строка.
Мой 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  

Ответы [ 2 ]

4 голосов
/ 02 марта 2009

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

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() на него из асинхронного потока, чтобы выполнить обновления индикатора выполнения.

1 голос
/ 02 марта 2009

Когда метод bgWorker1.RunWorkerAsync (); называется событием, запускаемым DoWork.

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

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

...