如何在加载xml文件期间使用进度条

我想在加载远程xml文件期间显示进度条。 我在Visual C#2008 Express Edition中使用Windows应用程序表单。

private void button1_Click(object sender, EventArgs e) { string text = textBox1.Text; string url = "http://api.bing.net/xml.aspx?AppId=XXX&Query=" + text + "&Sources=Translation&Version=2.2&Market=en-us&Translation.SourceLanguage=en&Translation.TargetLanguage=De"; XmlDocument xml = new XmlDocument(); xml.Load(url); XmlNodeList node = xml.GetElementsByTagName("tra:TranslatedTerm"); for (int x = 0; x < node.Count; x++ ) { textBox2.Text = node[x].InnerText; progressbar1.Value = x; } } 

上面的代码不能显示进度条加载..请建议我一些代码。 提前致谢

您希望通过进度条反映出什么? 而是下载文件(因为它很大)或处理文件?

进度条反映处理文件

您的进度条不会更改,因为您的方法是同步的 – 单位结束时不会发生任何其他事情。 BackgroundWorker类完美地针对这类问题而设计。 它以异步方式执行主要工作,并且能够报告进度已更改。 以下是如何更改tour方法以使用它:

 private void button1_Click(object sender, EventArgs e) { string text = textBox1.Text; string url = "http://api.bing.net/xml.aspx?AppId=XXX&Query=" + text + "&Sources=Translation&Version=2.2&Market=en-us&Translation.SourceLanguage=en&Translation.TargetLanguage=De"; XmlDocument xml = new XmlDocument(); xml.Load(url); XmlNodeList node = xml.GetElementsByTagName("tra:TranslatedTerm"); BackgroundWorker worker = new BackgroundWorker(); // tell the background worker it can report progress worker.WorkerReportsProgress = true; // add our event handlers worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.RunWorkerCompleted); worker.ProgressChanged += new ProgressChangedEventHandler(this.ProgressChanged); worker.DoWork += new DoWorkEventHandler(this.DoWork); // start the worker thread worker.RunWorkerAsync(node); } 

现在,主要部分:

 private void DoWork(object sender, DoWorkEventArgs e) { // get a reference to the worker that started this request BackgroundWorker workerSender = sender as BackgroundWorker; // get a node list from agrument passed to RunWorkerAsync XmlNodeList node = e.Argument as XmlNodeList; for (int i = 0; x < node.Count; i++) { textBox2.Text = node[i].InnerText; workerSender.ReportProgress(node.Count / i); } } private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // do something after work is completed } public void ProgressChanged( object sender, ProgressChangedEventArgs e ) { progressBar.Value = e.ProgressPercentage; } 

反映下载文件的进度条

尝试使用HttpWebRequest将文件作为流来获取。

 // Create a 'WebRequest' object with the specified url. WebRequest myWebRequest = WebRequest.Create(url); // Send the 'WebRequest' and wait for response. WebResponse myWebResponse = myWebRequest.GetResponse(); // Obtain a 'Stream' object associated with the response object. Stream myStream = myWebResponse.GetResponseStream(); long myStreamLenght = myWebResponse.ContentLength; 

所以现在你知道这个XML文件的长度了。 然后你必须异步读取流中的内容( BackgroundWorkerStreamReader是一个好主意)。 使用myStream.PositionmyStreamLenght计算进度。

我知道我不是很具体,但我只是想让你朝着正确的方向前进。 我认为在这里写下所有这些内容是没有意义的。 在这里,您可以使用链接来帮助您处理StreamBackgroundWorker

问题是你正在使用窗口线程,并且在完成button1_Click之前窗口无法重绘。

使用BackgroundWorker,您可以通过调用backgroundworker.ReportProgress来报告进度

进度条在这里不起作用,因为这是所有“同步”代码。 Click事件阻止UI更新。

有2种解决方案。

您可以创建后台线程来处理XML文件,后台线程将进度报告给前台。 我建议使用BackgroundWorker ,但在执行此操作之前还有很多需要学习的地方。

更简单的解决方案(尽管不是最佳的)是通过在每次进度更新后调用Application.DoEvents()来刷新表单。 这应该只被视为短期解决方案,因为如果任务不快,那么您的应用程序可能会冻结。

这两种解决方案都有一个缺点 – 当您的进度条刷新时,您的应用程序也将处理任何事件。 因此,您必须在处理任务时手动禁用UI,并在完成后重新启用它。

前段时间,我为这个问题创建了一个可重用的解决方案。 我创建了一个带有委托的“ProgressDialog”。 进度对话框执行委托,捕获进度,更新进度条,甚至计算剩余时间。 使用ProgressDialog的好处是我可以在“模态”模式下显示对话框,该模式会阻止对主UI的访问,甚至可以阻止Click事件的完成。
不幸的是,我没有任何代码可以分享,只是想法。

首先,它可能会让你看得太快 – 如果你正在进行测试,请尝试将Sleep放在那里,但是,进一步说,它没有更新的原因是你正在处理并且发生在与主UI相同的线程上正在使用。

您可以让程序通过调用Application.DoEvents()来处理所有事件,但通过这样做,您还可以重新处理用户可能点击的任何内容(包括此按钮) – 所以如果您想要DoEvents并确保不结束处理其他工作,在方法启动时禁用表单。

所有这一切,一个更好的模型是线程你的工作并更新计时器或回调上的进度条。