最近做了一个本地和远程服务器数据的同步,突发念头尝试了一下窗体程序。因为同步数据操作非常耗时,所以用了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该方法才可用)。
代码如下:
代码 using System.Drawing; 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(); } }}
转载于:https://www.cnblogs.com/shu756232/archive/2010/10/11/1848050.html
相关资源:C# BackgroundWorker组件学习入门介绍