2

I have some sample source code below with 2 lock statements. During my test run I click 'r1RefreshButton' to put showReport1 method into a forever loop. Then I click 'r2RefereshButton' to check if lock is doing as intended.

I found out that the lock on showReport2 does not really lock. 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

3 Answers 3

5

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.

Read more here: http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

Sign up to request clarification or add additional context in comments.

Comments

1

If you are intending for the process in 'showReport2()' to wait until 'showReport1()' is finished, you could use an AutoResetEvent. 'showReport2()' would use WaitOne() instead of lock(), and showReport1() would call Set() to signal it was done.

1 Comment

Thanks but i think i have to create separate threads for showReport2() and showReport1() to make it work. Anyway does events have priority level? I mean does the latest event should finish first before the previous executing event can continue? This is what I observed from my test run here
0

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. This will make your "ShowReport2" to wait until your "ShowReport1" is done. AutoResetEvent works to syncronize different threads. In the constructor of AutoResetEvent pass in false so its not set when you run it first time.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.