4

Is there a construct in c# that is like lock { }, but works when called from an event handler i.e. waits for the code block to complete before handling a subsequent event.

The problem I am having is that lock { } only prevents other threads from obtaining a lock on the object, but if an event handler on the same thread is called, the execution of code within the lock block is interrupted, and the new event is handled before returning to the execution of the original code.

object DoStuffLock = new object(); public void DoStuff() { lock (DoStuffLock) { // Do stuff that we don't want to be interrupted, // but because it is called from an event handler // it still can be interrupted despite the lock } } 

I am currently working around the problem like this (but it is hardly ideal):

object DoStuffLock = new object(); // this gets called from an event, and therefore can be interrupted, // locking does not help, so launch separate thread public void DoStuff() { var x = new Thread(DoStuffInternal); x.Start(); } private void DoStuffInternal() { lock (DoStuffLock) { // Do stuff that we don't want to be interrupted } } 
2
  • A thread cannot be 'interrupted' by an event. You haven't diagnosed the real problem. Commented Apr 5, 2011 at 20:06
  • Indeed - you are correct - I hadn't diagnosed the real problem. Commented Apr 5, 2011 at 20:47

4 Answers 4

4

The problem I am having is that lock { } only prevents other threads from obtaining a lock on the object, but if an event handler on the same thread is called

This really can't happen. If your thread is executing, an event can't occur on the same thread - it would have to be raised on a different thread.

That being said, your "second approach" is, in many ways, superior in any case. There's an implicit assumption that event handlers will return very quickly. A "blocking" event handler is typically a sign of a bad design, and will potentially cause problems, especially since the event publisher will not be expecting the event to block.

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

3 Comments

The event in question is fired by a FileSystemWatcher, and the code in DoStuff() returns very quickly. Despite this, if the FileSystemWatcher fire multiple events in very quick succession (and it often does), the code in DoStuff() gets interrupted to handle the new event.
@Matthew: You can do the lock without a separate thread. FileSystemWatcher raises events on a threadpool thread - so your lock would work fine there. It will never raise it on the same thread, since your code is executing. As a result, it will never interrupt your code - it may run 2 copies simultaneously (which makes the debugger look like it's interuptting, but check the threads window..). If this isn't desirable, a lock in your method will protect it without the need for a separate thread launch.
You are of course correct - the problem lay elsewhere - and running the locked code in a separate thread just appeared to "fix" the problem by delaying its execution - thanks for insisting that I was was wrong and making me recheck everything for a second time.
0

Think about locking code, not the object.

Use the same lock object to lock pieces of code that can't be entered simultaneously.

Besides, Locks don't stop interruption, they just stop access to the same piece of code from 2 threads simultaneously.

Comments

0

UI events are all called fromt the same thread. lock is designed to protect from multiple threads. lock is specifically designed to allow the same thread to call the same lock more than once, otherwise a deadlock can occur.

I think your second solution is the correct one. If you have some piece of code that must execute in a block, then you execute it on a new thread.

Comments

0

In operating systems like Windows you can not make any assumptions about the order of events handling. This can be done only with real time operating systems.

What you can do in your case is you could increase your thread priority. That should give your thread more time (relative to other threads). More info about threads priority in .net can be found here: http://msdn.microsoft.com/en-us/library/system.threading.threadpriority.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.