zoukankan      html  css  js  c++  java
  • 【编写高质量代码C#】建议72:在线程同步中使用信号量

    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(); }

      

  • 相关阅读:
    sql 删除
    sql 修改
    sql 新增
    sql UNION 和UNION ALL 数据连接查询
    WITH AS 子查询部分【mysql5.7及以下不支持,mysql8.0及sqlserver支持】
    sql 高级开窗函数row_number() over()和row_number() over(partition by)【mysql5.7及以下不支持,mysql8.0及sqlserver支持】
    sql 查询去重
    sql 常用聚合函数介绍
    sql 分组(group by)
    NPM 私有仓库搭建
  • 原文地址:https://www.cnblogs.com/Med1tator/p/6431409.html
Copyright © 2011-2022 走看看