锁定语句未按预期工作

本文关键字:工作 语句 锁定 | 更新日期: 2023-09-27 18:30:34

我在下面有一些带有 2 个锁定语句的示例源代码。在我的测试运行期间,我单击"r1RefreshButton"将showReport1方法放入永久循环中。然后我单击"r2RefereshButton"以检查锁定是否按预期执行。

我发现showReport2上的锁并没有真正锁定。我错过了什么吗?

public partial class TestReportsForm : Form
{
    private static readonly Object thisLock = new Object();
    public TestReportsForm() { InitializeComponent(); }
    private void showReport1()
    {
        lock (thisLock)
        {
            r1RefreshButton.Enabled = false;
            try
            {
                // while loop is used to simulate long process
                while (true)
                {
                    Application.DoEvents();
                }
            }
            catch (Exception ex)
            {
                String errorMessage = "Error encountered'n'n" +
                       "Error details: 'n" +
                       ex.Message;
                MessageBox.Show(this, errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                r1RefreshButton.Enabled = true;
            }
        }
    }
    private void r1RefreshButton_Click(object sender, EventArgs e)
    {
        showReport1();
    }
    private void showReport2()
    {
        lock (thisLock)
        {
            r2RefreshButton.Enabled = false;
            try
            {
                Application.DoEvents();
                // long process here
            }
            catch (Exception ex)
            {
                String errorMessage = "Error encountered'n'n" +
                       "Error details: 'n" +
                       ex.Message;
                MessageBox.Show(this, errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                r2RefreshButton.Enabled = true;
            }
        }
    }
    private void r2RefreshButton_Click(object sender, EventArgs e)
    {
        showReport2();
    }
}    

编辑:我从 C# 锁定事件中找到了类似的主题

锁定语句未按预期工作

这两个函数在同一线程上运行。锁保持在线程级别。

因此,在 GUI 线程上运行的所有代码都"具有"锁。

在此处阅读更多内容: http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

如果您打算让"showReport2()"中的进程等到"showReport1()"完成,则可以使用AutoResetEvent。'showReport2()' 将使用 WaitOne() 而不是 lock(),而 showReport1() 会调用 Set() 来表示它已完成。

根据您的要求,我会使用 AutoResetEvent,在您的"ShowReport2"中,您等待事件被设置,因此当您的"ShowReport1()"完成时,它会在 AutoResetEvent 上调用该集。这将使您的"显示报告2"等到您的"显示报告1"完成。自动重置事件用于同步不同的线程。在 AutoResetEvent 的构造函数中传入 false,因此首次运行时不会设置它。

http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx