BackgroundWorker是一个中使用.net框架自己提供的更新ui的控件。这样不会造成跨线程处理数据的问题。
在C#中,BackgroundWorker控件允许在单独的专用线程上运行操作。 耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面(UI)似乎处于停止响应状态。如果需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用BackgroundWorker类方便地解决问题。
界面:
代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BackgroundWorkerDemo
{
public partial class Form1 : Form
{
private BackgroundWorker _demoBGWorker = new BackgroundWorker();
public Form1()
{
InitializeComponent();
this.progressBarSum.Maximum = 100;
_demoBGWorker.WorkerReportsProgress = true;
_demoBGWorker.WorkerSupportsCancellation = true;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
try
{
btnCancel.Enabled = true;
Console.WriteLine("button1_Click");
Thread my_thread = Thread.CurrentThread;
Console.WriteLine("button1_Click:" + my_thread.ManagedThreadId);
if (_demoBGWorker != null)
{
_demoBGWorker = null;
_demoBGWorker = new BackgroundWorker();
}
_demoBGWorker.WorkerReportsProgress = true;
_demoBGWorker.WorkerSupportsCancellation = true;
_demoBGWorker.ProgressChanged += BGWorker_ProgressChanged;
_demoBGWorker.DoWork += BGWorker_DoWork;
_demoBGWorker.RunWorkerCompleted += BGWorker_RunWorkerCompleted;
_demoBGWorker.RunWorkerAsync(100);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
//开始工作事件
private void BGWorker_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("BGWorker_DoWork");
Thread my_thread = Thread.CurrentThread;
Console.WriteLine("BGWorker_DoWork:" + my_thread.ManagedThreadId);
BackgroundWorker bgWorker = sender as BackgroundWorker;
int endNumber = 0;
if (e.Argument != null)
{
endNumber = (int)e.Argument;
}
int sum = 0;
for (int i = 0; i <= endNumber; i++)
{
sum += i;
string message = "Current sum is: " + sum.ToString();
//ReportProgress 方法把信息传递给 ProcessChanged 事件处理函数。
//第一个参数类型为 int,表示执行进度。
//如果有更多的信息需要传递,可以使用 ReportProgress 的第二个参数。
//这里我们给第二个参数传进去一条消息。
bgWorker.ReportProgress(i, message);
Thread.Sleep(100);
//在操作的过程中需要检查用户是否取消了当前的操作。
if (bgWorker.CancellationPending == true)
{
e.Cancel = true;
break;
}
}
}
//更新ui事件
private void BGWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine("BGWorker_ProgressChanged");
Thread my_thread = Thread.CurrentThread;
Console.WriteLine("BGWorker_ProgressChanged:" + my_thread.ManagedThreadId);
//修改进度条的显示。
this.progressBarSum.Value = e.ProgressPercentage;
//如果有更多的信息需要传递,可以使用 e.UserState 传递一个自定义的类型。
//这是一个 object 类型的对象,您可以通过它传递任何类型。
//我们仅把当前 sum 的值通过 e.UserState 传回,并通过显示在窗口上。
string message = e.UserState.ToString();
this.labelSum.Text = message;
}
private void btnCancel_Click(object sender, EventArgs e)
{
try
{
Console.WriteLine("btnCancel_Click");
Thread my_thread = Thread.CurrentThread;
Console.WriteLine("btnCancel_Click:" + my_thread.ManagedThreadId);
_demoBGWorker.CancelAsync();
_demoBGWorker.ProgressChanged -= BGWorker_ProgressChanged;
_demoBGWorker.DoWork -= BGWorker_DoWork;
_demoBGWorker.RunWorkerCompleted -= BGWorker_RunWorkerCompleted;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
///任务处理完触发事件
private void BGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
try
{
Console.WriteLine("BGWorker_RunWorkerCompleted");
Thread my_thread = Thread.CurrentThread;
Console.WriteLine("BGWorker_RunWorkerCompleted:" + my_thread.ManagedThreadId);
//如果用户取消了当前操作就关闭窗口。
if (e.Cancelled)
{
this.Close();
}
//计算已经结束,需要禁用取消按钮。
this.btnCancel.Enabled = false;
//计算过程中的异常会被抓住,在这里可以进行处理。
if (e.Error != null)
{
Type errorType = e.Error.GetType();
switch (errorType.Name)
{
case "ArgumentNullException":
case "MyException":
//do something.
break;
default:
//do something.
break;
}
}
//计算结果信息:e.Result
//use it do something.
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}