views:

510

answers:

4

I suspect this is a very dumb question: what is the correct syntax for an interruptible lock statement in C#? E.g. get lock; if lock is interrupted before locked code finishes, return false out of the enclosing method. Probably totally the wrong terminology... Thanks.

+1  A: 

What you mean by "interrupted" is unclear.

Interruption by Exception

private bool SomeLockingMethod(object foo)
{
    // Verify foo is valid

    try
    {
       lock(foo)
       {
          while(something)
          {
             // Do stuff

             Thread.Sleep(1); // Possibly yield to another 
                              // thread calling Thread.Interrupt
          }
       }

       return true;
    }
    catch(ThreadInterruptedException ex)
    {
       // Handle exception
    }

    return false;
}

If the return true isn't reached, then something happened while the lock on foo was held, and the code returns false. The lock is automatically released, either way.

Another thread can interrupt this one by calling Thread.Interrupt.

"Interruption" from code

If you're the one "interrupting" the code, it could be as simple as

private bool SomeLockingMethod(object foo)
{
    // Verify foo is valid

    lock(foo)
    {
       // Do stuff

       if(shouldInterrupt)
       {
          return false;
       }

       // Do more stuff
    }

    return true;
 }

Again, the lock is automatically released, whether or not there is an "interruption".

Interruption because someone else is trying to acquire the lock

Possibly this is what you're looking for; in this case you may want to use something else, like a Semaphore or ManualResetEvent.

Daniel LeCheminant
I am trying to replicate Java code which manages a bounded buffer. Receive and Send are synchronized methods. Part of the Receive is as follows, symbolically:while empty { try { wait(); } catch (InterruptedException e) { return false }} Similarly for Send, using full
Paul Morrison
@Paul: I've updated my answer to reflect this; It now shows how you would use a `Thread.Interrupt` and a caught `ThreadInterruptedException`
Daniel LeCheminant
That's great! Thanks, @Daniel
Paul Morrison
A: 

I'm not sure what you're trying to get at here. The purpose of the lock statement is that you should not get interrupted so you can ensure consistent behavior.

What are you trying to accomplish here?

Brian Rasmussen
+2  A: 

You can have a timeout while aquiring a lock using Monitor.TryEnter; and likewise, within a lock you can do things like Monitor.Wait/Monitor.Pulse to temporarily yield the lock, but you can't be interrupted as such.

The main time interrupt applies might be in Thread.Sleep, which can be interrupted with Thread.Interrupt - but again, this won't yank control out of an executing method block.

What exactly is it that you are trying to achieve? With more context we can probably help more...

Marc Gravell
What did you mean by "you can't be interrupted as such"? Surely any method is interruptable...?
Paul Morrison
Some interop stuff is completely non-interruptible. And even if it can be interrupted (via exception) - you probably shouldn't.
Marc Gravell
A: 

You might also have a look at transaction scope, added in 2.0, which may be what you're looking for (unknown, due the ambiguity in your question). It allows you to attempt some actions, then roll back if those actions were not completed properly.

See here for more details.

Travis