請務必檢查您 RunWorkerCompleted 事件處理常式中的 AsyncCompletedEventArgs.Error 屬性,再嘗試存取可能會受 DoWork 事件處理常式影響的 RunWorkerCompletedEventArgs.Result 屬性或任何其他物件。XXXEventArgs 通常都是 Event 第二參數,RunWorkerCompleted Event 明明就是 RunWorkerCompletedEventArgs,只能自行解讀為要先判斷 RunWorkerCompletedEventArgs.Cancel 和 RunWorkerCompletedEventArgs.Error,再來存取 RunWorkerCompletedEventArgs.Result
在 RunWorkerCompletedEventArgs.Result 內也有相關說明
您 RunWorkerCompleted 事件處理常式應該一律檢查 Error 和 Cancelled 屬性,然後再存取 Result 屬性。 如果發生例外狀況,或已取消作業,存取 Result 屬性引發例外狀況。Application.DoEvents 的存在,可以讓迴圈進行時,UI 還可以進行操作,但該作法會造成 CPU 飆高,所以要利用 Thread.Sleep 睡一下,該效果透過工作管理員就可以觀察到
while (this.backgroundWorker1.IsBusy)
{
progressBar1.Increment(1);
// Keep UI messages moving, so the form remains
// responsive during the asynchronous operation.
Application.DoEvents();
// 避免 CPU 飆高
Thread.Sleep(1);
}
該範例 Code 整理
using System.Xml;
using System.Threading;
namespace BackgroundWorkerDownload
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.DoWork += BackgroundWorker1_DoWork;
backgroundWorker1.RunWorkerCompleted += BackgroundWorker1_RunWorkerCompleted;
}
private XmlDocument document = null;
private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Set progress bar to 100% in case it's not already there.
progressBar1.Value = 100;
if (e.Error == null)
{
MessageBox.Show(document.InnerXml, "下載完成");
}
else
{
MessageBox.Show("無法下載檔案,下載失敗", "下載檔案", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// Enable the download button and reset the progress bar.
btnDownload.Enabled = true;
progressBar1.Value = 0;
}
private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
document = new XmlDocument();
Thread.Sleep(10000);
// Replace this file name with a valid file name.
document.Load(@"http://www.tailspintoys.com/sample.xml");
}
private void btnDownload_Click(object sender, EventArgs e)
{
// Start the download operation in the background.
backgroundWorker1.RunWorkerAsync();
// Disable the button for the duration of the download.
btnDownload.Enabled = false;
// Once you have started the background thread you
// can exit the handler and the application will
// wait until the RunWorkerCompleted event is raised.
// Or if you want to do something else in the main thread,
// such as update a progress bar, you can do so in a loop
// while checking IsBusy to see if the background task is
// still running.
while (this.backgroundWorker1.IsBusy)
{
progressBar1.Increment(1);
// Keep UI messages moving, so the form remains
// responsive during the asynchronous operation.
Application.DoEvents();
// 避免 CPU 飆高
Thread.Sleep(1);
}
}
}
}
沒有留言:
張貼留言