Blocking a function call in C#
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 ac开发者_如何学运维tually using threads...but I am using timers that call the function repeatedly and it's also called among different classes.
Use a lock
:
private static object lockObject = new object();
lock(lockObject) {
// ... code goes here...
}
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.
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?"
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.
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.
精彩评论