Question

Using the lock statement, one can "ensure that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released."

What if the behaviour I want is that if another thread tries to enter the locked code, it will just skip the whole code (instead of waiting the lock to be released)? An idea that come to my mind is using a flag, something like

if(flag) return;
flag = true;
//do stuff here
flag =false;

But I know this is not safe because two threads can pass the first line before anyone set to true, or the flag being never set to false in case of exceptions.. Can you suggest an improvement or an alternative?

Was it helpful?

Solution

Use this overload of Monitor.TryEnter, which lets you specify a timeout.

Attempts, for the specified amount of time, to acquire an exclusive lock on the specified object.

Return Value Type: System.Boolean true if the current thread acquires the lock without blocking; otherwise, false.

In your case, you probably want to use a timeout of close to TimeSpan.Zero.

If you don't want the thread attempting to take the lock to wait for any length of time, you can just this overload of Monitor.TryEnter, which does not accept a TimeSpan argument. This method will immediately return without waiting - very close to the sentiment of the flag technique you are trying to use.

OTHER TIPS

You need Semaphores with a limit 1 and timeout period 0 miliseconds

By using Semaphore you can say that only a limited number of threads can access a piece of code at a time.

See this sample for how to use it

You need to use this method for waiting

bool WaitOne(int millisecondsTimeout)

specify timeout period = 0; in this way your waiting threads will wait 0 second which means they will simply skip the code

Example

class SemaphoreExample    
{ 
// Three reserved slots for threads
public static Semaphore Pool = new Semaphore(1, 0);

public static void Main(string[] args) 
{    
// Create and start 20 threads    
for (int i = 0; i < 20; i++) 
{ 
    Thread t = new Thread(new ThreadStart(DoWork)); 
    t.Start(); 
}

Console.ReadLine();    
}

private static void DoWork()    
{    
// Wait 0 miliseconds  
SemaphoreExample.Pool.WaitOne(0);


#region Area Protected By Semaphore    
Console.WriteLine("Acquired slot...");

for (int i = 0; i < 10; i++) 
{   
    Console.WriteLine(i + 1);  
}   
Console.WriteLine("Released slot...");    

#endregion        
// Release the semaphore slot    
SemaphoreExample.Pool.Release();    
}    
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top