C#中的MessageBox、锁和System.Windows.Forms.Timer问题

MessageBox, lock and System.Windows.Forms.Timer problem in C#

我相信我对 lock 的工作方式或 System.Windows.Forms.Timer 在 C# 中的工作方式有误解。

所以我制作了一个简单的 Windows 表单应用程序 (.NET Framework),并从工具箱中向 Form 添加了 TimerButtonButton 在单击时启动 TimerTimer 在虚拟对象上输入 lock 并在 Tick 事件中阻止它。对于 ButtonClick 事件,我有以下方法:

private void button1_Click(object sender, EventArgs e)
{
    timer1.Enabled = true;
}

对于 TimerTick 事件,我有这个方法:

readonly object lockObj = new object();

private void timer1_Tick(object sender, EventArgs e)
{
    lock (lockObj)
    {
        MessageBox.Show("Entered the lock!");
        MessageBox.Show("Exiting the lock...");
    }
}

其他一切都保留为默认值,没有额外的代码。

我希望这个程序显示一个带有文本 "Entered the lock!"MessageBox,然后在我关闭它之后以及下面一个带有消息 "Exiting the lock..." 我认为锁会被释放并且排队的 Tick 事件(如果有的话)将获得锁,过程重复。相反,"Entered the lock!" MessageBox 保持打开多次而不必关闭它,就好像每个 Tick 事件调用都会进入锁定,即使没有人释放它。

我试图在控制台应用程序中复制它,但没有成功。如果能提示导致此问题的原因,我将不胜感激,这样我就知道该去哪里查看了。

您可以在 Windows 表单应用程序中测试的替代代码:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Lock_Test_2
{
    public partial class Form1 : Form
    {
        Timer timer1;

        readonly object lockObj = new object();

        public Form1()
        {
            InitializeComponent();

            Button button1 = new Button();
            button1.Location = new Point(100, 100);
            button1.Size = new Size(187, 67);
            button1.Text = "button1";
            button1.Click += button1_Click;
            Controls.Add(button1);

            timer1 = new Timer();
            timer1.Tick += timer1_Tick;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            lock (lockObj)
            {
                MessageBox.Show("Entered the lock!");
                MessageBox.Show("Exiting the lock...");
            }
        }
    }
}

System.Windows.Forms.Timer 通过 windows 消息循环调度其事件。

MessageBox.Show 显示一个消息框,然后将 windows 消息循环作为嵌套循环。这可以包括为计时器分派更多事件。

由于只涉及一个线程(UI 线程),并且 lock 是可重入的,这就是显示多个消息框的原因。