Skip to content

线程同步 - 信号同步 -AutoResetEvent(2)

🏷️ C# 学习 C#

下面的例子中,本意是两个线程都阻塞,收到信号时都继续工作。

但实际的运行结果却是,收到信号后,一个继续工作,另一个继续阻塞,直到再一次收到信号,另一个才会继续工作。

这时应该用 ManualResetEvent 替换 AutoResetEvent

cs
using System;
using System.Threading;
using System.Windows.Forms;

namespace WaitHandleSample
{
    public partial class Form2 : Form
    {
        AutoResetEvent autoResetEvent = new AutoResetEvent(false);

        public Form2()
        {
            InitializeComponent();
            // 允许新线程访问主线程的控件
            CheckForIllegalCrossThreadCalls = false;
        }

        private void btnStartAThread_Click(object sender, EventArgs e)
        {
            StartThread1();
            StartThread2();
        }

        private void StartThread1()
        {
            Thread tWork1 = new Thread(() => {
                label1.Text = "线程 1 启动。。。" + Environment.NewLine;
                label1.Text += "开始处理一下实际的工作" + Environment.NewLine;
                // 省略工作代码
                label1.Text += "我开始等待别的线程给我信号,才愿意继续下去" + Environment.NewLine;
                autoResetEvent.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();
                label2.Text += "我继续做了一些工作,然后结束了";
            });
            tWork2.IsBackground = true;
            tWork2.Start();
        }

        private void btnSet_Click(object sender, EventArgs e)
        {
            // 给在 autoResetEvent 上等待的线程一个信号
            autoResetEvent.Set();
        }
    }
}