【编写高质量代码C#】建议72:在线程同步中使用信号量

本文通过实例介绍了如何使用AutoResetEvent和ManualResetEvent进行线程间的同步操作,并对比了两者之间的区别。此外,还展示了如何利用信号机制模拟网络通信中的在线与离线状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.使用信号机制提供线程同步的一个简单例子

        AutoResetEvent autoResetEvent = new AutoResetEvent(false);
        private void button1_Click(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            Thread tWork = new Thread(() =>
            {
                label1.Text = "线程启动..." + Environment.NewLine;
                label1.Text += "开始处理一些实际的工作" + Environment.NewLine;
                //省略工作代码
                label1.Text += "我开始等待别的线程给我信号,才愿意继续下去" + Environment.NewLine;
                autoResetEvent.WaitOne();
                label1.Text += "我继续做一些工作,然后结束了!";
                //省略工作代码
            });
            tWork.IsBackground = true;
            tWork.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //将事件状态设置为终止状态,允许一个或多个等待线程继续
            autoResetEvent.Set();
        }

  以上例子中,点击按钮1执行到autoResetEvent.WaitOne()不再往下,点击按钮2才会继续往下执行。

2.AutoResetEvent和ManualResetEvent的区别:

使用AutoResetEvent,autoResetEvent.Set()只能使一个线程继续,而ManualResetEvent,manualResetEvent.Set()可使多个线程继续执行。

例子如下:

 

      private void button2_Click(object sender, EventArgs e)
        {
            //将事件状态设置为终止状态,允许一个或多个等待线程继续
            //autoResetEvent.Set();
            manualResetEvent.Set(); 
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            StartThread1();
            StartThread2();
        }
        private void StartThread1()
        {
            Thread tWork1 = new Thread(() =>
            {
                label1.Text = "线程1启动..." + Environment.NewLine;
                label1.Text += "开始处理一些实际的工作" + Environment.NewLine;
                //省略工作代码
                label1.Text += "我开始等待别的线程给我信号,才愿意继续下去" + Environment.NewLine;
                //autoResetEvent.WaitOne();
                manualResetEvent.WaitOne();
                label1.Text += "我继续做一些工作,然后结束了!";
                //省略工作代码
            });
            tWork1.IsBackground = true;
            tWork1.Start();
        }

        private void StartThread2()
        {
            Thread tWork2 = new Thread(() =>
            {
                label2.Text = "线程2启动..." + Environment.NewLine;
                label2.Text += "开始处理一些实际的工作" + Environment.NewLine;
                //省略工作代码
                label2.Text += "我开始等待别的线程给我信号,才愿意继续下去" + Environment.NewLine;
                //autoResetEvent.WaitOne();
                manualResetEvent.WaitOne();
                label2.Text += "我继续做一些工作,然后结束了!";
                //省略工作代码
            });
            tWork2.IsBackground = true;
            tWork2.Start();
        }

3.模拟网络通信

        private void button4_Click(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            Thread t = new Thread(() => {
                while (true)
                {
            //原理:没隔3秒检测接收,若未接收到a.Set(),则离线 bool re=a.WaitOne(3000); if (re) { label3.Text = string.Format("时间:{0},{1}", DateTime.Now.ToString(), "在线"); } else { label3.Text = string.Format("时间:{0},{1}", DateTime.Now.ToString(), "离线"); } } }); t.IsBackground = true; t.Start(); } private void button5_Click(object sender, EventArgs e) { a.Set(); }

  

转载于:https://www.cnblogs.com/Med1tator/p/6431409.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值