C# 异步控件 backgroundWorker
// .net4.8 Winform
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
static ManualResetEvent manualResetEvent = new ManualResetEvent(true); // 暂停线程
public Form1()
{
InitializeComponent();
button2.Enabled = false; // Pause 按钮不可用
button3.Enabled = false; // Stop 按钮不可用
toolStripStatusLabel1.Text = "准备就绪";
}
private void timer1_Tick(object sender, EventArgs e) // 取现在时间
{
//Control.CheckForIllegalCrossThreadCalls = false;
/// 这句代码就是说在这个类中我们不检查跨线程的调用是否合法(如果没有加这句话运行也没有异常,那么说明系统以及默认的采用了不检查的方式)。
/// 然而,这种方法不可取。我们查看CheckForIllegalCrossThreadCalls 这个属性的定义,就会发现它是一个static的,也就是说无论我们在项目的什么地方修改了这个值,他就会在全局起作用。
/// 而且像这种跨线程访问是否存在异常,我们通常都会去检查。如果项目中其他人修改了这个属性,那么我们的方案就失败了,我们要采取另外的方案。
DateTime dateTime = DateTime.Now;
label2.Text = dateTime.ToString("mm:ss");
}
public static int T; // 返回任务数值
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) // 任务安排
{
BackgroundWorker worker = sender as BackgroundWorker;
Control.CheckForIllegalCrossThreadCalls = false;
for (int i = 0; i < 101; i++)
{
T = i;
//Task.Delay (100).Wait();
Thread.Sleep(100); // 延迟, 毫秒
worker.ReportProgress(i); // 报告任务状态, 接受 int 值
manualResetEvent.WaitOne(); // 等待接受 manualResetEvent 信号.
if (worker.CancellationPending) // 如果用户取消了任务就跳出; 每次执行都判断一次.
{
e.Cancel = true;
return;
}
}
button1.Enabled = true; // Pause 按钮可用
button2.Enabled = false; // Pause 按钮不可用
button3.Enabled = false; // Stop 按钮不可用
//progressBar1.Value = 0;
e.Result = T; // 返回计算结果
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage; // 返回 worker.ReportProgress(i) 的值;
label3.Text = e.ProgressPercentage.ToString();
//button1.Text = e.ProgressPercentage.ToString();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null) // 判断是否有错误, 如果有错误则会提示信息
{
toolStripStatusLabel1.Text = "错误" + e.Error.Message;
}
if (e.Cancelled) // 判断是否取消了操作
{
toolStripStatusLabel1.Text = "取消操作";
}
else // 如果没有错误则会从 e.Result = T 取回返回结果;
{
toolStripStatusLabel1.Text = "操作完成";
}
}
private void button1_Click(object sender, EventArgs e)
{
toolStripStatusLabel1.Text = "执行中...";
MessageBoxButtons buttons = MessageBoxButtons.OK; // 创建一个按钮
if (worker.IsBusy) // 判断任务是否在执行中
{
manualResetEvent.Reset(); // 暂停线程
MessageBox.Show("任务正在执行中...", "信息", buttons);
manualResetEvent.Set(); // // 恢复线程
//return;
}
else
{
button2.Enabled = true; // Pause 按钮可用
button3.Enabled = true; // Stop 按钮可用
//button1.Enabled = false; // Start 按钮不可用
worker.RunWorkerAsync(); // 执行 backgroundWorker1_DoWork 事件
}
}
private void button2_Click(object sender, EventArgs e)
{
button1.Enabled = false; // Pause 按钮可用
// 根据按钮名称来分别执行任务, 这样的方式比较笨,也不严谨.
if (button2.Text=="Pause")
{
button3.Enabled = false; // Stop 按钮不可用
manualResetEvent.Reset(); // 暂停线程
button2.Text = "Continue";
toolStripStatusLabel1.Text = "暂停";
}
else if (button2.Text == "Continue")
{
button3.Enabled = true;
manualResetEvent.Set(); // 继续线程
button2.Text = "Pause";
toolStripStatusLabel1.Text = "执行中...";
}
}
private void button3_Click(object sender, EventArgs e)
{
button1.Enabled = false; // Pause 按钮可用
button2.Enabled = false; // Stop 按钮可用
worker.WorkerSupportsCancellation = true; // 是否支持异步取消
if (worker.IsBusy)
{
worker.CancelAsync();
button3.Text = "Close";
return;
}
Close(); // 关闭窗口
}
}
}
## 执行过程
## 添加的控件
文章编写or整理的内容由作者完成,引用or参考会给出原文链接。