Pat*_*son 1 c# class backgroundworker
我是C#的新手,我正试图围绕面向对象的编程.这就是我想要完成的事情:
我有一个带有Form1的Windows窗体应用程序和一个名为connect(相同的命名空间)的单独类.
我知道在执行大量代码时使用后台工作人员是一种好习惯(以免冻结UI).所以我在Form1中创建了一个后台工作程序和一个progresschanged句柄.我试图找到如何在单独的连接类中触发progresschange.在Form1的progresschange块中,我有一个case/switch,用于确定屏幕上显示的文本.
解决这个问题的最佳方法是什么?我可以把背景工作者传给其他班级吗?
小智 5
您也可以将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";
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的表单上,您只需处理事件.
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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,BackgroundWorker.ReportProgress()方法的第二个参数(UserState)可以传递任何对象.它不必是一个字符串.例如,如果从数据库中检索了行/行,则可以通过此方法将行传递回用户界面.对于BackgroundWorker.DoWork方法的e.Result也是如此.
埃里克
| 归档时间: |
|
| 查看次数: |
2046 次 |
| 最近记录: |