Monday, April 25, 2011

Syntax for interruptible lock in C#

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.

From stackoverflow
  • 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.

    Paul Morrison : 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
    Daniel LeCheminant : @Paul: I've updated my answer to reflect this; It now shows how you would use a `Thread.Interrupt` and a caught `ThreadInterruptedException`
    Paul Morrison : That's great! Thanks, @Daniel
  • 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?

  • 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...

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

0 comments:

Post a Comment