C# wimform实现计数器
涉及知识点:
1.使用委托、事件完成界面1与界面2中的信息传输;
2.线程的操作与取消
展示
Step1
wimform拖拉拽先完成如下图布局;
Step2 事件知识点
事件是一种能让对象或类具备通知能力的成员。
使用:用于对象或类之间的动作协调与信息传递。
举个实际生活中的例子:闹钟响了你起床,孩子饿了你做饭…(这里面隐含者订阅关系)
相当于(1)我有一个事件;(2)一个人或一群人关心我的这个事件;(3)我的这个事件发生了;(4)关心这个事件的人会被依次通知到;(5)被通知到的人,根据拿到的事件信息对事件进行响应;
根据这个,可以好好理解下上述的例子,闹钟响了你起床,孩子饿了你做饭;
事件模型常常涉及5个部分:
- 事件的拥有者
- 事件成员
- 事件的响应者
- 事件的处理器
- 事件订阅
在Form2中定义
// Form2.cs
// 定义一个委托和一个事件
public delegate void SetLabelDelegate(string info);
public event SetLabelDelegate SetLabelEvent;
Form2是事件的拥有者,拥有事件 SetLabelEvent;
Form1是事件的响应者,Label1会发生变化,让Label发生变化的即是事件处理器;
// Form1.cs
public partial class Form1 : Form
{
private Form2 form2;
public Form1()
{
InitializeComponent();
form2 = new Form2();
}
/*
* Form2: 事件拥有者
* 拥有事件 SetLabelEvent
* Form1: 事件响应者
* 拥有事件处理器 Form2_SetLabelEvent
*
* 订阅关系 事件 += 处理器
*/
private bool isSubscribed = false;
private void button1_Click(object sender, EventArgs e)
{
// 检查是否已经订阅,避免重复订阅
if (!isSubscribed)
{
form2.SetLabelEvent += Form2_SetLabelEvent; // 订阅
isSubscribed = true;
}
form2.Show();
// 监听界面2的关闭事件,取消订阅
form2.FormClosed += Form2_FormClosed;
}
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
// 界面2关闭时取消订阅事件
form2.SetLabelEvent -= Form2_SetLabelEvent;
}
private void Form2_SetLabelEvent(string info) // 事件处理器
{
label1.Text = info;
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
/*
* Form2: 事件拥有者
* 拥有事件 SetLabelEvent
* Form1: 事件响应者
* 拥有事件处理器
*
* 订阅关系
*/
// 定义一个委托和一个事件
public delegate void SetLabelDelegate(string info);
public event SetLabelDelegate SetLabelEvent;
// 计数变量与计数状态
private int counter = 0;
private bool isRunning = false;
// 取消线程
private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
private CancellationToken cancellationToken;
private async void StartTimer()
{
decimal sudu = numericUpDown1.Value;
cancellationToken = cancellationTokenSource.Token;
try
{
while (isRunning)
{
await Task.Delay((int)(1000 / sudu), cancellationToken); // 阻塞
if (cancellationToken.IsCancellationRequested)
break; // 如果取消请求已经发出,退出循环
counter++;
// 在主线程上更新 form1 label1
this.Invoke((Action)(() =>
{
if (SetLabelEvent != null) // 触发事件
{
// 相当于通过委托执行Form1中的 事件处理器函数
SetLabelEvent(counter.ToString());
}
}
));
}
}
catch (TaskCanceledException)
{
// 捕获 TaskCanceledException 异常以避免抛出
}
}
private void button1_Click(object sender, EventArgs e)
{ // 计数启动
if (!isRunning)
{
isRunning = true;
StartTimer();
}
}
private void button2_Click(object sender, EventArgs e)
{
isRunning = false;
}
private void button3_Click(object sender, EventArgs e)
{
// 发出取消请求
cancellationTokenSource.Cancel();
//重置
isRunning = false;
counter = 0;
// 更新标签以显示"0"
this.Invoke((Action)(() =>
{
if (SetLabelEvent != null)
{
//SetLabelEvent("0");
SetLabelEvent(counter.ToString());
}
}));
// 重置 CancellationTokenSource 和 CancellationToken,以便重新开始线程
cancellationTokenSource = new CancellationTokenSource();
cancellationToken = CancellationToken.None;
}
private void button4_Click(object sender, EventArgs e)
{
//isRunning = false;
this.Hide();
}
}