LittleFunny
LittleFunny

Reputation: 8375

C#: Using lock will block later calls.

Using lock, i know if there are subsequent call, the later call will be waiting until previous call finishes. What if I don't want to have subsequent call to wait and let it skip that block of code.

I currently create a keyboard on a device which listen to other device input. I have a timer checking the device's input in 500milliseconds.

keyboardTimer = new Timer(500);
            keyboardTimer.Elapsed += (sender, e) =>
            {  
                lock (RemoteControlPage.keyboardLock)
                { 
                    var keyboardStatus = LauncherClient.Instance.GetKeyboardStatus();

                    if (keyboardStatus.Visibility == KEYBOARDVISIBILITY.SHOW)
                    { 
                        //Show keyboard
                    }
                    else if (keyboardStatus.Visibility == KEYBOARDVISIBILITY.HIDE)
                    {
                        //Hide keyboard 
                    }
                    else {
                        Debug.WriteLine("Keyboard = Do Nothing");
                    }
                }
            }; 

In the code, I have a lock in case two or more call entering it each time. Elapsed will fire again even though the previous call not finished processing leading the later call waiting. Is there a way to skip from execution instead of waiting the previous call finished processing.

Upvotes: 2

Views: 133

Answers (2)

spender
spender

Reputation: 120380

All this synchronization biz is a pain to get right. If you don't want to re-enter in a very unambiguous, easily understandable way, just go for an asynchronous loop:

async Task CheckKeyboard(CancellationToken token = default(CancellationToken))
{
     while(!token.IsCancellationRequested)
     {
         //talk to the keyboard
         await Task.Delay(500); //or some cunningly figured out wait time
     }
}

Upvotes: -1

InBetween
InBetween

Reputation: 32740

You can use the Monitor class:

keyboardTimer = new Timer(500);
keyboardTimer.Elapsed += (sender, e) =>
{  
    if (Monitor.TryEnter(RemoteControlPage.keyboardLock))
    { 
        try
        {
            var keyboardStatus = LauncherClient.Instance.GetKeyboardStatus();

            if (keyboardStatus.Visibility == KEYBOARDVISIBILITY.SHOW)
            { 
                //Show keyboard
            }
            else if (keyboardStatus.Visibility == KEYBOARDVISIBILITY.HIDE)
            {
                //Hide keyboard 
            }
            else
            {
                Debug.WriteLine("Keyboard = Do Nothing");
            }
        }
        finally
        {
            Monitor.Exit(RemoteControlPage.keyboardLock);
        }
    }
 }; 

Upvotes: 3

Related Questions