How to restrict to one method call at a time? - c#

I'd like to know how to implement the following restriction: One method in my Windows Service should not be called again before the earlier call has been finished. The method in question goes thru couple of database tables and it's very important that this process won't be called again before it's finished. I have a setting that defines how often my service will activate and under normal circumstances it never activates before the earlier call has been finished (because whole process should not take more than couple of minutes and the interval is set to 10 minutes) but thats not sure enough. I guess.
How to implement this?

You can use a named Mutex or a named Semaphore to ensure that only one holder of the Mutex/Semaphore is executing at once. As a commenter pointed out, keep in mind you must be careful not to abandon a mutex or improperly acquire/release a semaphore.

One way would be to use locking:
private readonly object myLock = new object();
private void MyMethod()
{
lock(myLock)
{
//code goes here
}
}
This ensures that this method can never be running more that once at a time.

I second the Mutex suggestion, but you might also want to take a look at transactions. Wrap your entire code in a transaction (this requires a using System.Transactions):
using(TransactionScope scope = new TransactionScope())
{
try
{
/* ... your current code here */
scope.Complete();
}
catch (Exception e)
{
/* Any appropriate error handling/logging here */
}
finally
{
}
}
A transactionscope automatically locks all related tables. You can reduce the restrictions and allow other processes to read, but not write to the data that your process is touching. You do this by passing options to the TransactionsScope constructor.

Well if all the code is localized you can set a boolean and check the boolean before executing the method, otherwise you can IPC and request the state before execution.

Some alternatives:
You can put a check in the call to check some flag or call Monitor.TryEnter and return with an error/do nothing if negative.
You can queue up calls (if you need this method to execute more than once) and only invoke when Monitor has been signaled.
If you don't mind blocking, and the method is on a separate thread, you can join the thread of the method you want to wait.
I'm sure there are others.

If you don't mind restricting one thread at a time to the entire object, then you can use:
Synchronization Contexts
Have your class inherit from ContextBoundObject
Apply a [Synchronization] attribute to the class.
The CLR will only allow one thread at a time to execute code per instance of this class. The others will block until the lock is released by the current thread.

This sounds like a serial workflow... Have you considered using a workflow framework?

If you want your function run with await/async
private static readonly SemaphoreSlim yourLock = new SemaphoreSlim(1, 1); //allow only 1 thread at time
...
private async Task<string> YourFunction() {
await yourLock.WaitAsync();
try
{
//your code go here
}
finally
{
yourLock.Release();
}
}

Related

Multithreading and Locking (Thread-Safe operations)

So I have a class with a few methods which all use locking in order to prevent weird things happening when someone uses an instance of my class with multiple threads accessing it:
public class SomeRandomClass
{
private object locker = new object();
public void MethodA()
{
lock (locker)
{
// Does something
MethodB();
}
}
public void MethodB()
{
lock (locker)
{
// Does something else
}
}
}
As we can see, MethodB() is automatically accessed by MethodA(), but that won't work since MethodA() has currently locked the locker object.
I want to make MethodB() accessible publicly, so you can call it manually whenever needed, but I do NOT want it to be used while MethodA() is doing things (that's why I'm using a locker object).
And of course I do not want MethodA() to do things while MethodB() is doing stuff. I basically want only one of all the methods to be used at the same time, but MethodA() needs to access MethodB() somehow without removing the lock (so that it stays completely thread-safe the whole time).
I really hope it is kind of understandable what I'm trying to ask... If there's any questions about my question, then please go ahead and post them below. Answers/Solutions are very much appreciated as well!
The solution is probably incredibly easy and I'm just not seeing it.
By the way, the above is supposed to be C#-code.
An easy solution would be to create a private method that contains what MethodB does that can be called by MethodA and another public MethodB
The private MethodB does not lock, only the public ones do.
For example:
public class SomeRandomClass {
private object locker = new object();
public void MethodA {
lock(locker) {
// exclusive club
// do something before calling _methodB
_methodB();
}
}
private void _methodB {
// do that, what used to be done by MethodB
}
public void MethodB {
//this one only exists to expose _methodB in a thread-safe context
lock(locker) {
_methodB();
}
}
}
P.S.
I think it is obvious to you and everyone else why your code is somewhat designed to create a deadlock.
Update:
Apparently lock(object) {} is re-entrant as pointed out in the comments, so the obvious deadlock isn't even one.
Locking forbids what you're trying to do -- that's its purpose.
One thing to do here is creating a private method that you can access from both methodA and methodB. That method wouldn't use locking, and wouldn't be thread safe, but could be called from either one of the locking methods.
You have race condition here: it make data incorrect. I suppose method A write static theVar variable of type string:
thread A -> call method A -> lock -> change theVar to "A"
thread B -> call method B -> wait because thread A keep lock
thread A -> release lock to call method B
The bug here: thread B process theVar of "A"
If method B only read theVar, it's Ok.
Your lock mechanism needs to allow locks to be taken in a recursive way (by the same thread only), usually called reentrant. lock (Monitor class internally).
It is legal for the same thread to invoke Enter more than once without it blocking; however, an equal number of Exit calls must be invoked before other threads waiting on the object will unblock.
See also Recursive / nested locking in C# with the lock statement
and Re-entrant locks in C#
As pointed out by Henk Holterman in the comment, the Monitor class is already reentrant. And the lock statement is managing the right amount of Enter and Exit calls to the underlying Monitor class.
The ReaderWriterLockSlim class is an example for a lock mechanism where one can choose between reentrant and non-reentrant. See https://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim(v=vs.110).aspx
var rwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
Replace your lock { ... } with
ReaderWriterLockSlim rwLock =
new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
...
try
{
rwLock.EnterWriteLock();
// Does something
}
finally
{
rwLock.ExitWriteLock();
}
```
The Code written by you is correct.
Because according to Microsoft, once the call is acquired even if program calls for lock in the same flow, it will not be blocked as lock is already with the thread.
The code works as below.
call "MethodA" -->acquire lock --> call "MethodB" (will not be blocked as thread is already acquired lock) and execution will be completed.
Call "MethodB" in between previous execution from another thread, the execution will be blocked as lock is with first thread.

It is ok to store a Thread in a static variable?

I want to make sure that I always create only one instance of a Thread so I built this:
private static volatile Thread mdmFetchThread = null;
private static object Locker = new object();
public void myMethod(){
string someParameter = getParameterDynamically();
lock(Locker)
{
// If an mdmFetchThread is already running, we do not start a new one.
if(mdmFetchThread != null && mdmFetchThread.ThreadState != ThreadState.Stopped)
{
// warn...
}
else
{
mdmFetchThread = new Thread(() => { doStuff(someParameter); });
mdmFetchThread.Start();
}
}
}
Is this ok to do or what could be possible pitfalls?
//Edit: As requested below a bit context: doStuff() is calling some external system. This call might timeout but I cant specify the timeout. So I call it in mdmFetchThread and do a mdmFetchThread.join(20000) later. To avoid that I call the external system twice, I created the static variable so that I can check if a call is currently ongoing.
Storing a thread in a static variable is OK (if you need at most one such thread per AppDomain). You can store whatever you want in static storage.
The condition mdmFetchThread.ThreadState != ThreadState.Stopped is racy. You might find it to be false 1 nanosecond before the thread exits. Then you accidentally do nothing. Maintain your own boolean status variable and synchronize properly. Abandon volatile because it is more complicated than necessary.
Consider switching to Task. It is more modern. Less pitfalls.
Consider using a Lazy<Task> to create the singleton behavior you want.
Add error handling. A crash in a background thread terminates the process without notifying the developer of the error.
Generally speaking if you are using statics to store state (such as a thread), then you might have a design flaw when attempting to scale out or when trying to manage the lifetime of the object. I usually try to avoid statics whenever possible.
An alternative might be to create a class that only manages a single thread to perform your task as an instance. This class might be responsible for passing data to your Thread or managing the state of it. For example, ensuring it is only run once, stopping the thread gracefully, or handling when the thread completes. If you wanted to scale out, then you'd just create multiple instances of your class each with their own thread that they manage. If you only wanted one, then just pass around a single instance.
If you're looking for ways to make this instance available to your entire application (which is usually the issue people are trying to solve when using static variables), then take a look into patterns like using ServiceContainers and IServiceProvider.

Creating multiple threads for same method on an instance on an object

I have a question. Is it possible and valid, if I have an object with a method DoSomething(), if I create multiple threads for this method, will it work and would it run as a seperate thread of its own?
E.g.
public class SomeClass
{
public void DoSomething()
{
//somethings done here
}
}
public class MainProgram
{
public MainProgram()
{
InitializeComponents();
}
protected override OnStart(string[] args)
{
SomeClass sc = new SomeClass();
Thread workerOne = new Thread(() => sc.DoSomething());
workerOne.Start();
Thread workerTwo = new Thread(() => sc.DoSomething());
workerTwo.Start(); //start a new thread calling same method
}
}
I hope that kind of explains what I mean. Would this work or cause any problems?
I am writing a program that needs to almost be realtime software, I am currently deciding whether initialising a new instance of SomeClass is better or not?
Hope someone can answer. If my question's dont make sense, please comment and I'll explain further!
Thanks,
Base33
PS The code was written specifically for the example :)
Each thread has a separate call stack, so yes they can both be using the same method on the same object. And indeed, if needed each thread can (via recursion) call the same method on the same instance multiple times if you really want.
However, what might trip you up is if you are using state in that object (instance or static fields, etc, and anything related from that state). You will need to ensure your access to any shared state gives full consideration (and presumably synchronisation) to multi-threaded access.
Yes you can do that. You will however have to make sure that your member accesses within that method are thread safe.
If you mutate the state of the object you should either lock your reads and writes (not speaking of any particular mechanism) or verify that it's harmless to interupt the method at any given time and that the other call on a different thread will still work correctly
Is it possible and valid, if I have an object with a method DoSomething(), if I create multiple threads for this method, will it work and would it run as a seperate thread of its own?
Yes it is possible. In your code example, DoSomething is being called on the same instance of SomeClass. Both threads share this. You have two distinct threads but one actual object being shared.
Would this work or cause any problems?
That entirely depends on your use case. It may or may not. If objects are shared, you need to synchronize access to them.
It has no problem. I will run without any error.
It is just like creating an object and call method on this object
twice. only fact is that two occurrence of calling same method is on
different thread.

Synchronization primitive "lock once"

I need a synchronization primitive which is similar to Monitor but doesn't require to Exit it as many times as I have enter it. If I enter Monitor by one thread and then reenter it by the same thread I will need to call Monitor.Exit twice. But I need to exit it by one call.
Now I use a some kind of Monitor wrapper which doesn't enter Monitor if it was already entered by current thread (and that's why then I can exit it by one call). But may be .NET Framework contains one?
I'm curious to know why you would ever call Monitor.Enter multiple times without an equal number of calls to Monitor.Exit. Typically any such synchronization code would look like this:
try
{
Monitor.Enter(lockObject);
// some code that needs to be synchronized
}
finally
{
Monitor.Exit(lockObject);
}
Assuming you are using try/finally wherever you acquire a lock using Monitor.Enter (which you should be), I'm having trouble seeing why you would need this "lock-once" class you're asking about.
In fact, you should basically never have to do this yourself anyway, as a much simpler approach that does essentially the same thing is to use a lock statement:
lock (lockObject)
{
// some code that needs to be synchronized
}
That said, I could certainly just be missing something.
how do you know it's the same thread and how to you ensure that when this threads leaves it is going to call exit before it leaves?
From the looks of it, you just need something else (in an outer level) that has the lock. Maybe an "entry point" method that locks and calls another method that has the meat of the work then you can call this other method many times without going past the lock.
public static void MethodOne()
{
lock (lockObj)
{
MethodTwo();
}
}
private static void MethodTwo()
{
//This method can be called multiple times
//without going past MethodOne and so you only
//lock once
}
private static void MethodThree()
{
}

Overriding C#'s Monitor.Enter and Monitor.Exit

I'm working on some big multi threaded project, now yesterday I had a deadlock (my first one ever), and I traced it by adding a Console.WriteLine("FunctionName: Lock on VariableName") and Console.WriteLine("FunctionName: Unlocking VariableName"). Adding all those was quite some work.
First of all, the program has a main loop that runs 2 times per second, that loop pulses some other threads to complete their work after the main loop has processed. Now what happened was that I had one thread in wait state to be pulsed, when it was pulsed it called another method that'd also wait to get pulsed, but the pulse already happened, and the thread won't pulse again until the action is actually completed.
Now what I want to do is override the Monitor.Enter and Monitor.Exit functions, without wrapping them in a class.
I've heard a lot about Reflection, but I have no idea how to apply it for this purpose, I know the easiest way to achieve it all is by just using a wrapper class, but then the lock keyword won't work anymore, and I'd have to convert all locks into Monitor.Enter try { } finally { Monitor.Exit }, that's huge amount of work.
So my question: How to override the Monitor.Enter and Monitor.Exit functions, while keeping access to the base function to do the actual lock?
And if that's impossible: How to override the lock statement to call my wrapper class instead of the Monitor.Enter and Monitor.Exit functions?
EDIT FOR CLARITY:
I request this just for allowing me to log when the locks happen, to make the debugging process easier, that also means I don't want to create my own locking mechanism, I just want to log when a lock is established and when it's released.
The close will also not be executed most of the time, only when I come across a threading problem.
It sounds like you're looking for lock helpers. Jon Skeet's MiscUtil has some:
http://www.yoda.arachsys.com/csharp/miscutil/usage/locking.html
The idea is that you replace your lock statements with using statements and thus preserve the try-finally structure:
class Example
{
SyncLock padlock = new SyncLock();
void Method1
{
using (padlock.Lock())
{
// Now own the padlock
}
}
void Method2
{
using (padlock.Lock())
{
// Now own the padlock
}
}
}
With regards to deadlock prevention, the library offers a specialized ordered lock:
class Example
{
OrderedLock inner = new OrderedLock("Inner");
OrderedLock outer = new OrderedLock("Outer");
Example()
{
outer.InnerLock = inner;
}
}
Of course, you could extend Jon's helpers, or simply create your own (for logging purposes, etc). Check out the link above for more information.
Don't do it! That sounds bonkers ;-)
A deadlock occurs when 2 (or more) threads are all waiting to simultaneously hold 2 (or more) locks. And each thread gets a lock and waits for the other one.
You can often redesign your code so each thread only requires a single lock - which makes deadlock impossible.
Failing that, you can make a thread give up the first lock if it can't acquire the second lock.
That's a very bad idea. I never had to override Monitor.Enter / Exit or lock to overcome a deadlock. Please consider redesigning your code!
For example, use ManualResetEvent for the pulsing.

Categories

Resources