简体   繁体   English

锁语句无法按预期工作

[英]lock statement not working as expected

I have some sample source code below with 2 lock statements. 我下面有一些带有2个锁语句的示例源代码。 During my test run I click 'r1RefreshButton' to put showReport1 method into a forever loop. 在测试运行期间,我单击“ r1RefreshButton”以将showReport1方法置于永久循环中。 Then I click 'r2RefereshButton' to check if lock is doing as intended. 然后,我单击“ r2RefereshButton”以检查锁定是否按预期进行。

I found out that the lock on showReport2 does not really lock. 我发现showReport2上的锁定并没有真正锁定。 Did I miss something? 我错过了什么?

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();
    }
}    

EDIT: I found similar topic from C# Locking from events 编辑:我从事件的C#锁定中发现了类似的主题

Both functions are running on the same thread. 这两个函数都在同一线程上运行。 Locks are held at thread-level. 锁保持在线程级别。

So all code running on the GUI thread "has" the lock. 因此,在GUI线程上运行的所有代码都具有“锁定”。

Read more here: http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx 在此处阅读更多信息: http : //msdn.microsoft.com/en-us/library/c5kehkcz.aspx

If you are intending for the process in ' showReport2() ' to wait until ' showReport1() ' is finished, you could use an AutoResetEvent . 如果您打算让' showReport2() '中的过程等待直到' showReport1() '完成,则可以使用AutoResetEvent ' showReport2() ' would use WaitOne() instead of lock(), and showReport1() would call Set() to signal it was done. showReport2() ”将使用WaitOne()而不是lock(),而showReport1()将调用Set()表示已完成。

As per your requirement I would go with AutoResetEvent, In your "ShowReport2" you wait for the event to be set, so when your "ShowReport1()" finishes, it calls the set on the AutoResetEvent. 根据您的要求,我将使用AutoResetEvent,在“ ShowReport2”中等待事件设置,因此,当“ ShowReport1()”完成时,它将在AutoResetEvent上调用该设置。 This will make your "ShowReport2" to wait until your "ShowReport1" is done. 这将使您的“ ShowReport2”等待直到“ ShowReport1”完成。 AutoResetEvent works to syncronize different threads. AutoResetEvent用于同步不同的线程。 In the constructor of AutoResetEvent pass in false so its not set when you run it first time. 在AutoResetEvent的构造函数中传递false,因此在您第一次运行它时不会设置它。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM