最近做了一个本地和远程服务器数据的同步,突发念头尝试了一下窗体程序。因为同步数据操作非常耗时,所以用了BackgroundWorker。网上搜罗了一下,大致用法如下:
主要的事件及参数。
1、DoWork——当执行BackgroundWorker.RunWorkerAsync方法时会触发该事件,并且传递DoWorkEventArgs参数;
2、ProgressChanged——操作处理中获得的处理状态变化,通过BackgroundWorker.ReportProgress(int)方法触发该事件,并且传递ProgressChangedEventArgs,其中包含了处理的百分比;
3、RunWorkerCompleted——异步操作完成后会触发该事件,当然如果需要在操作过程中结束可以执行BackgroundWorker.CancelAsync方法要求异步调用中止,并且在异步委托操作中检测BackgroundWorker.CancellationPending属性如果为true的话,跳出异步调用,同时将DoWorkEventArgs.Cancel属性设为true,这样当退出异步调用的时候,可以让处理RunWorkerCompleted事件的函数知道是正常退出还是中途退出。
主要的方法。
1、BackgroundWorker.RunWorkerAsync——“起动”异步调用的方法,有两次重载RunWorkerAsync(),RunWorkerAsync(object argument),后者提供了一个参数以供异步调用使用。
2、BackgroundWorker.ReportProgress——有时候需要在一个冗长的操作中向用户不断反馈进度,这样的话就可以调用的ReportProgress(int percent),在调用 ReportProgress 方法时,触发ProgressChanged事件。提供一个在 0 到 100 之间的整数,它表示后台活动已完成的百分比。你也可能提供任何对象作为第二个参数,允许你 给事件处理程序传递状态信息。作为传递到此过程的 ProgressChangedEventArgs 参数属性,百分比和你自己的对象(如果提供的话)均要被传递到 ProgressChanged 事件处理程序。这些属性被分别命名为 ProgressPercentage 和 UserState,并且你的事件处理程序可以以任何需要的方式使用它们。(注意:只有在BackgroundWorker.WorkerReportsProgress属性被设置为true该方法才可用)。
3、BackgroundWorker.CancelAsync——但需要退出异步调用的时候,就调用的这个方法。但是样还不够,因为它仅仅是将BackgroudWorker.CancellationPending属性设置为true。你需要在具体的异步调用处理的时候,不断检查BackgroudWorker.CancellationPending是否为true,如果是真的话就退出。(注意:只有在BackgroundWorker.WorkerSupportsCancellation属性被设置为true该方法才可用)。
代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace mobeyForm
{
public partial class Form1 : Form
{
private System.ComponentModel.BackgroundWorker backgroundWorker;
public Form1()
{
InitializeComponent();
// 定义线程开始
backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true ;
backgroundWorker.WorkerSupportsCancellation = true ;
backgroundWorker.DoWork += new DoWorkEventHandler(backgroundCalculator_DoWork);
backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundCalculator_ProgressChanged);
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundCalculator_RunWorkerCompleted);
updateStatus(String.Empty);
updateResult(String.Empty);
}
private void button1_Click( object sender, EventArgs e)
{
this .button1.Enabled = false ;
this .btnClose.Enabled = false ;
this .progressBar1.Value = 0 ;
// 将调用DoWork事件
updateStatus( " 程序执行中,请等待…… " );
backgroundWorker.RunWorkerAsync(chkStock.Checked);
}
/// <summary>
/// 线程 启动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundCalculator_DoWork( object sender, DoWorkEventArgs e)
{
bool updateStock = ( bool )e.Argument; // 是否更新库存
string reslut = string .Empty;
// string reslut = new Components.DataUpdate().updateDataTable();
long successCount = 0 ;
long uploaded = 0 ;
// string websql = "select as_Id,as_ContactMan from C_Address";
string websql = " select ProductId,SKU,CostPrice from Hishop_Products " ;
if (updateStock)
websql = " select ProductId,SKU,CostPrice,Stock from Hishop_Products " ;
SqlConnection serverConn = null ;
try
{
serverConn = new SqlConnection(Components.Const.ServerConnStr);
}
catch (Exception ex)
{
reslut = string .Format( " 【请求服务器链接】过程中发生异常已被取消,错误信息:“{0}” " , ex.Message);
e.Result = reslut;
// e.Cancel = true;
return ;
// 日志
}
DataSet serverDS = new DataSet();
DataTable serverDT = new DataTable();
SqlDataAdapter serverAD = new SqlDataAdapter(websql, serverConn);
SqlCommandBuilder cmb = new SqlCommandBuilder(serverAD); //
serverAD.Fill(serverDS, " Hishop_Products " );
serverDT = serverDS.Tables[ 0 ];
// serverDt= new Components.DataUpdate().getData(websql, Components.Const.ServerConnStr);
backgroundWorker.ReportProgress( 30 ); // 回发进度
if (serverDT != null )
{
if (serverDT.Rows.Count > 0 )
{
try
{
for ( int i = 0 ; i < serverDT.Rows.Count; i ++ )
{
string SKU = serverDT.Rows[i][ " SKU " ].ToString();
// string sql ="select top 1 as_ContactMan from C_Address where as_Id=" + id;
string sql = string .Format( " select top 1 Qty,Price from GoodsStocks left join ptype on PtypeId=typeId where UserCode='{0}' " , SKU);
try
{
DataTable locDt = new Components.DataUpdate().getData(sql, Components.Const.LocalConnStr);
if (locDt.Rows.Count > 0 )
{
string stock = string .Empty;
if (updateStock)
stock = locDt.Rows[ 0 ][ " Qty " ].ToString().Trim();
string price = locDt.Rows[ 0 ][ " Price " ].ToString().Trim();
if (stock.Length > 0 && price.Length > 0 )
{
if (updateStock)
{
int istock = 0 ;
serverDT.Rows[i][ " Stock " ] = Int32.TryParse(stock, out istock) == true ? Convert.ToInt32(stock) : Convert.ToInt32(Convert.ToDouble(stock));
}
serverDT.Rows[i][ " CostPrice " ] = Convert.ToDecimal(price);
}
}
successCount += 1 ;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
// 日志
}
}
}
catch (Exception ex)
{
// e.Cancel = true;
reslut = string .Format( " 【更新数据】过程中发生异常已被取消,错误信息:“{0}” " , ex.Message);
e.Result = reslut;
return ;
// 日志
}
backgroundWorker.ReportProgress( 70 ); // 回发进度
#region 更新到服务器
try
{
uploaded = serverAD.Update(serverDS, " Hishop_Products " );
serverDS.AcceptChanges();
}
catch (Exception ex)
{
// e.Cancel = true;
reslut = string .Format( " 【数据更新到服务器】过程中发生异常已被取消,错误信息:“{0}” " , ex.Message);
e.Result = reslut;
return ;
// 日志
}
#endregion
}
}
reslut = string .Format( " 成功更新数目:{0},发生更改项:{1} " , successCount, uploaded);
e.Result = reslut;
}
/// <summary>
/// 线程 完成
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundCalculator_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
// updateResult("程序被取消");
updateResult(e.Result.ToString());
updateStatus( " 程序执行被取消 " );
}
else
{
updateResult(e.Result.ToString());
updateStatus( "" );
}
this .button1.Enabled = true ;
this .btnClose.Enabled = true ;
this .progressBar1.Value = 100 ;
}
/// <summary>
/// 线程 取消
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnCancel( object sender, EventArgs e)
{
backgroundWorker.CancelAsync();
}
/// <summary>
/// 操作处理中获得的处理状态变化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void backgroundCalculator_ProgressChanged( object sender, ProgressChangedEventArgs e)
{
this .progressBar1.Value = e.ProgressPercentage;
}
/// <summary>
/// 界面提示信息提示
/// </summary>
/// <param name="status"></param>
private void updateStatus( string status)
{
this .calcStatus.Text = status;
}
/// <summary>
/// 运行结果提示
/// </summary>
/// <param name="result"></param>
private void updateResult( string result)
{
this .label1.Text = result;
}
private void btnClose_Click( object sender, EventArgs e)
{
this .Close();
this .Dispose();
}
}
}