首页 > 解决方案 > C# 中的 MessageBox、锁和 System.Windows.Forms.Timer 问题

问题描述

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

因此,我制作了一个简单的 Windows 窗体应用程序(.NET Framework),并在工具箱中添加了一个和Timer一个。单击时开始,然后在虚拟对象上输入 a并在事件中阻止它。对于's事件,我有以下方法:ButtonFormButtonTimerTimerlockTickButtonClick

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

对于Timer'sTick事件,我有这个方法:

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...");
    }
}

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

我希望这个程序显示一个MessageBox带有 text的单曲"Entered the lock!",然后在我关闭它之后,还有下一个带有"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...");
            }
        }
    }
}

标签: c#locking

解决方案


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

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

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


推荐阅读