views:

213

answers:

5

Hello All,

How do I block a function call in C#?

This function gets repeatedly called by different classes.I want to lock it up so that no one else can use it until I perform my current operation. Then,i want to release it again.

Please help..

Thanks

Edit:I'm not actually using threads...but I am using timers that call the function repeatedly and it's also called among different classes.

+6  A: 

Use a lock:

private static object lockObject = new object();

lock(lockObject) {
  // ... code goes here...
}
Mehrdad Afshari
what is that object? I just need to lock my function...
Josh
You don't lock functions. You lock objects. To lock a "function", you try to acquire a lock on an object at the beginning and release it at the end.
Mehrdad Afshari
the object is just some random object. synchronization locks are attached to specific objects. So just having some particular shared object that your function always checks for its lock is sufficient.
Yuliy
the standard approach is to use a non-static lockObject unless you are locking access to static resources.
DW
DW: Apparently, the OP wants to block the whole function from running, regardless of the instance so he should use a `static` lock object.
Mehrdad Afshari
+3  A: 

If you are accessing this function from multiple threads you need some sort of synchronization.

If we are talking about single-threaded code, why not just use a boolean that stores if your function is currently "usable"?

Update:
As you added that you are not using threads, IMO a simple bool would suffice.
If you need more states, you could create an enum and set that accordingly.

weichsel
If you need more states, you could create an enum and set that accordingly. -- or simply store a reference to the "owner" class somewhere and check whether your object currently "owns" the instance.
Mehrdad Afshari
I'd still go with the `lock` method, since it buys you multi-threading abilities for free if you need them down the road. Or if your code is publicly callable someone can't accidentally break your method by calling it from multi-threaded code.
jasonh
But if his issue is reentrancy (what else can it be if it isn't being called from multiple thread?) then the lock won't do anything for him since it allows recursive lock acquisition on the same thread.
Phil
+1  A: 

The standard way to do is to throw an InvalidOperationException, signaling the client of your code that your class object is not yet in a state to be usable.

Hans Passant
+2  A: 

Depending on the timers you use, you may be using threads. UI timers (Windows.Forms.Timers) only run on the UI thread, so they will not be called reentrantly. However, System.Threading timers use threadpool threads, so your code can be called reentrantly on different threads - in which case you need some thread synchronisation (locks).

If you are not using threads, then your code can only be called re-entrantly if it does somethng that causes itself to be called. The obvious case is when it calls itself, but less obvious are cases where applying some action causes a chain of events that result in your method being called again - a "feedback loop".

So, the first step is to ask "is my code being called reentrantly?"
The second step is to ask "why?"
Then, if your code is causing the reentrancy, "how can I chnage the operaiton of my code so it doesn't call itself".
Or, if it's threaded, "where should I put locks to ensure that only one thread can execute this code at a time?"

Jason Williams
A: 

You state that you are not using threads. If this is really the case, then it should not be possible for the function to be called multiple times unless your block of code does something which can causes reentrancy.

I notice one of the other answers here suggests using the lock statement. Note, this will only work if the real issue is that you are calling the function from multiple threads. If the issue is actually that you have a single thread but are doing something which results in reentering the function (e.g. pumping the UI message queue) then the lock statement will not prevent the code from executing multiple times - this is because the lock statement allows recursive locks on the same thread - i.e. it only disallows concurrent access from different threads.

So, noticing that you mention the use of timers, your particular situation is going to depend on which type of timers you are using - if you are using the timer from the System.Threading namespace, then the lock is probably what you will want (because you actually are executing the code on different threads since this timer uses the thread pool to execute your callbacks). If however, you are using the timers from the System.Windows.Forms namespace, then you are using a timer that always executes using the UI thread (via processing the UI message queue), and in this case it's most likely that the issue you have is some kind of reentrancy issue.

If the issue is reentrancy, and you are not calling the code from different threads then instead of a lock which won't work, you should be able to just use a boolean variable to record when you are already in the function, and disallow reentrancy.

Having said that, if you do have this type of reentrancy you may have a problem with your design.

Note, one thing with timers people sometimes fail to take into account is whether it is ok for the timer to be triggered again whilst you are still performing operations resulting from a previous triggering of the timer. In order to avoid this, I personally rarely set a timer to trigger repetitively - instead I set it to trigger once only, and then reenable the timer at the end of processing the operations performed in response to the trigger. This means that the time duration (without adjustment) becomes the interval between the end of processing the last triggered operation and the start of the next triggered operation.

Usually though this is actually what you want since you don't want the same operation to be triggered while the previous operation has not yet completed.

Phil