锁定语句未按预期工作

时间:2013-09-09 04:24:31

标签: c# locking

下面有一些示例源代码,包含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# Locking from events

中找到了类似的主题

3 个答案:

答案 0 :(得分:5)

两个函数都在同一个线程上运行。锁定在线程级别。

因此,在GUI线程上运行的所有代码都“拥有”锁。

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

答案 1 :(得分:1)

如果您打算在' showReport2()'中等待“ showReport1()”完成后,您可以使用AutoResetEvent 。 ' showReport2()'会使用WaitOne()而不是lock(),而 showReport1()会调用Set()来表示已完成。< / p>

答案 2 :(得分:0)

根据您的要求,我会使用AutoResetEvent,在您的“ShowReport2”中等待设置事件,因此当您的“ShowReport1()”完成时,它会调用AutoResetEvent上的设置。这将使您的“ShowReport2”等到“ShowReport1”完成。 AutoResetEvent用于同步不同的线程。在AutoResetEvent的构造函数中传递false,因此在第一次运行时不会设置它。

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

相关问题