您還可以將您的BackgroundWorker放置在Connect類中。在這個類中,您可以創建事件來將進度和完成情況報告給調用表單。
using System;
using System.ComponentModel;
namespace WindowsTest
{
public class Connect
{
BackgroundWorker bw;
public Connect()
{
bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.DoWork +=new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
}
public delegate void ProgressChangedHandler(Object sender, ProgressChangedEventArgs e);
public event ProgressChangedEventHandler ProgressChanged;
protected void RaiseProgressChangedEvent(ProgressChangedEventArgs e)
{
if (ProgressChanged == null)
{
return;
}
ProgressChanged(this, e);
}
public delegate void WorkCompleteEventHandler(Object sender, RunWorkerCompletedEventArgs e);
public event WorkCompleteEventHandler WorkComplete;
protected void RaiseWorkCompleteEvent(RunWorkerCompletedEventArgs e)
{
if (WorkComplete == null)
{
return;
}
WorkComplete(this, e);
}
public void Cancel()
{
if (bw.IsBusy)
{
bw.CancelAsync();
}
}
public void BeginLongRunningProcess()
{
bw.RunWorkerAsync();
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
RaiseWorkCompleteEvent(e);
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
RaiseProgressChangedEvent(e);
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
if (ConnectToServer())
{
bw.ReportProgress(0, "Connected to server");
e.Result = LongRunningProcess();
if (e.Result.ToString() == "Cancelled")
{
e.Cancel = true;
return;
}
}
else
{
//Connection failed
e.Cancel = true;
}
}
private bool ConnectToServer()
{
//Attempt connection
return true;
}
private string LongRunningProcess()
{
int recordCount = 250;
for (int i = 0; i <= recordCount; i++)
{
if (bw.CancellationPending)
{
return "Cancelled";
}
double progress = ((double)i/(double)recordCount) * 100;
bw.ReportProgress((int)progress , "Running Process");
System.Threading.Thread.Sleep(25);
}
return "The result is 2";
}
}
}
然後在窗體上,您只需處理事件。
namespace WindowsTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Connect connect;
private void btnConnect_Click(object sender, EventArgs e)
{
connect = new Connect();
connect.ProgressChanged += new ProgressChangedEventHandler(connect_ProgressChanged);
connect.WorkComplete += new Connect.WorkCompleteEventHandler(connect_WorkComplete);
connect.BeginLongRunningProcess();
}
private void connect_WorkComplete(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
lblStatus.ForeColor = Color.Red;
lblStatus.Text = string.Format("Status: {0}", "User Cancelled!");
return;
}
if (e.Error != null)
{
//Process exception
lblStatus.Text = string.Format("Status: {0}", "Error!");
lblStatus.ForeColor = Color.Red;
return;
}
lblStatus.Text = string.Format("Status: Complete. {0}", e.Result);
}
private void connect_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
lblStatus.Text = string.Format("Status: {0}", e.UserState.ToString());
}
private void btnCancel_Click(object sender, EventArgs e)
{
if (connect != null)
{
connect.Cancel();
}
}
}
}
注意,第二參數的BackgroundWorker.ReportProgress的(UserState)()方法可以通過任何對象。它不一定是一個字符串。例如,如果您從數據庫檢索到一行/多行,則可以通過此方法將該行傳回給用戶界面。 BackgroundWorker.DoWork方法的e.Result也是如此。
Eric
爲什麼要在連接類上處理progress_changed? –
連接類運行通過一些事情,如連接到一個SQL服務器,運行一個或兩個查詢。我希望能夠最終更改form1上的statusstrip標籤以反映當前正在發生的事情(例如顯示連接到服務器,運行查詢等)。如果我可以使用另一種不鎖定用戶界面的方法從連接類更新form1上的statusstrip標籤,那麼我就是爲了它。 –