C#实现计数器,委托事件、线程的操作与取消

C# wimform实现计数器

涉及知识点:
1.使用委托、事件完成界面1与界面2中的信息传输;
2.线程的操作与取消

展示

Step1

wimform拖拉拽先完成如下图布局;
在这里插入图片描述在这里插入图片描述

Step2 事件知识点

事件是一种能让对象或类具备通知能力的成员。
使用:用于对象或类之间的动作协调与信息传递。

举个实际生活中的例子:闹钟响了你起床,孩子饿了你做饭…(这里面隐含者订阅关系)

相当于(1)我有一个事件;(2)一个人或一群人关心我的这个事件;(3)我的这个事件发生了;(4)关心这个事件的人会被依次通知到;(5)被通知到的人,根据拿到的事件信息对事件进行响应;

根据这个,可以好好理解下上述的例子,闹钟响了你起床,孩子饿了你做饭;

事件模型常常涉及5个部分:

  1. 事件的拥有者
  2. 事件成员
  3. 事件的响应者
  4. 事件的处理器
  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();
        }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值