Using Named Mutex - c#

I have two instances running of same Windows Service. They check the health of each other and report if any issue is found. I have a critical job that needs to be performed so I am running it with a fail-over approach, it runs in Master, and if Master is not responding it runs in slave. This job needs to communicate over a specific serial port, I am trying to use Mutex to check for race condition. I dont have access to production, so before deploying I want to make sure my approach is fine. So please suggest if my use of Mutex is fine for the given case.
if (iAmRunningInSlave)
{
HealthClient hc = new HealthClient();
if (!hc.CheckHealthOfMaster())
return this.runJobWrapper(withMutex, iAmRunningInSlave);
else
return true; //master is ok, we dont need to run the job in slave
}
return this.runJobWrapper(withMutex, iAmRunningInSlave);
And then in runJobWrapper
bool runJobWrapper(bool withMutex, bool iAmRunningInSlave)
{
if (!withMutex)
return this.runJob(iAmRunningInSlave); //the job might be interested to know
Mutex mutex = null;
string mutexName = this.jobCategory + "-" + this.jobTitle; //this will be unique for given job
try
{
mutex = Mutex.OpenExisting(mutexName);
return false; //mutex is with peer, return false which will re-trigger slave
}
catch
{
try
{ //mean time mutex might have created, so wrapping in try/catch
mutex = new Mutex(true /*initiallyOwned*/, mutexName);
return this.runJob(iAmRunningInSlave); //the job might be interested to know where I am running
}
finally
{
if (null!=mutex) mutex.ReleaseMutex();
}
return false;
}
}

I had a similar issue recently.
The design of the Mutex class is a bit weird/different from the normal classes in .NET.
Using OpenMutex to check for an existing Mutex is not really nice as you have to catch an exception.
A better approach is to use the
Mutex(bool initiallyOwned, string name, out bool createdNew)
constructor, and check the value returned by createdNew.

You don't look to check the return value from runJobWrapper anywhere - is this intentional? It is not obvious what the return value actually means anyway. Also you really shouldn't catch each any every exception that OpenExisiting could possibly throw - Out of memory? Stack overflow? etc. etc. Just catch the one you mean to handle correctly.
Also your code looks to be somewhat fragile - I wouldn't be surprised if you have race conditions.

I noticed that mutex.ReleaseMutex() was not releasing the mutex immediately..I had to call GC.Collect()

Related

Detect Boolean value changes inside Thread

I have a c++ dll function that i want to run inside the C# thread.
Some times I need to cancel that thread, and here is the issue :
Thread.Abort() is evil from the multitude of articles I've read on
the topic
The only way to do that was to use a bool and check it's value periodically.
My problem that even i set this value to true it didn't change and still equal to false in c++ code. However when I show a MessageBox that value changed and it works fine.
Any ideas why that value changed only when the MessageBox showed and please tell me how to fix that issue.
C#
public void AbortMesh()
{
if (currMeshStruct.Value.MeshThread != null && currMeshStruct.Value.MeshThread.IsAlive)
{
//here is my c++ Object and cancel mesh used to set bool to true;
MeshCreator.CancelMesh();
}
}
C++
STDMETHODIMP MeshCreator::CancelMesh(void)
{
this->m_StopMesh = TRUE;
return S_OK;
}
when I test the boolean value
if (m_StopMesh)
return S_FALSE;
The value here is always false even i call AbortMesh()
if (m_StopMesh)
return S_FALSE;
MessageBox(NULL,aMessage,L"Test",NULL);
if (m_StopMesh) // here the value is changed to true
return S_FALSE;
The non-deterministic thread abortion (like with Thread.Abort) is a really bad practice. The problem is that it is the only practice that allows you to stop your job when job does not know that it could be stopped.
There is no library or framework in .NET I know of that allows to write threaded code that could allow you to run an arbitrary task and abort it at any time without dire consequences.
So, you was completely write when you decided to use manual abort using some synchronization technique.
Solutions:
1) The simplest one is using of a volatile Boolean variable as it was already suggested:
C#
public void AbortMesh()
{
if (currMeshStruct.Value.MeshThread != null && currMeshStruct.Value.MeshThread.IsAlive)
{
MeshCreator.CancelMesh();
}
}
C++/CLI
public ref class MeshCreator
{
private:
volatile System::Boolean m_StopMesh;
...
}
STDMETHODIMP MeshCreator::CancelMesh(void)
{
this->m_StopMesh = TRUE;
return S_OK;
}
void MeshCreator::ProcessMesh(void)
{
Int32 processedParts = 0;
while(processedParts != totalPartsToProcess)
{
ContinueProcessing(processedParts);
processedParts++;
if (this->m_StopMesh)
{
this->MakeCleanup();
MessageBox(NULL,aMessage,L"Test",NULL);
}
}
}
Such code should not require any synchronization if you do not make any assumptions on completion of thread after the CancelMesh call - it is not instantaneous and may take variable amount of time to happen.
I don't know why the use of the volatile didn't help you, but there are few moments you could check:
Are you sure that the MeshCreator.CancelMesh(); method call actually happen?
Are you sure that m_StopMesh is properly initialized before the actual processing begins?
Are you sure that you check the variable inside the ProcessMesh often enough to have decent response time from your worker and not expecting something instantaneous?
2)Also if you use .NET 4 or higher you could also try to use the CancellationToken-CancellationTokenSource model. It was initially designed to work with Tasks model but works well with standard threads. It won't really simplify your code but taking into an account the async nature of your processing code will possibly simplify future integration with TPL
CancellationTokenSource cancTokenSource = new CancellationTokenSource();
CancellationToken cancToken = cancTokenSource.Token;
Thread thread = new Thread(() =>
{
Int32 iteration = 0;
while (true)
{
Console.WriteLine("Iteration {0}", iteration);
iteration++;
Thread.Sleep(1000);
if (cancToken.IsCancellationRequested)
break;
}
});
thread.Start();
Console.WriteLine("Press any key to cancel...");
Console.ReadKey();
cancTokenSource.Cancel();
3) You may want to read about interlocked class,monitor locks, autoresetevents and other synchronization, but they are not actually needed in this application
EDIT:
Well, I don't know how it couldn't help(it is not the best idea, but should work for such a scenario), so I'll try later to mock your app and check the issue - possibly it has something to do with how MSVC and CSC handle volatile specifier.
For now try to use Interlocked reads and writes in your app:
public ref class MeshCreator
{
private:
System::Boolean m_StopMesh;
...
}
STDMETHODIMP MeshCreator::CancelMesh(void)
{
Interlocked::Exchange(%(this->m_StopMesh), true);
return S_OK;
}
void MeshCreator::ProcessMesh(void)
{
Int32 processedParts = 0;
while(processedParts != totalPartsToProcess)
{
ContinueProcessing(processedParts);
processedParts++;
if (Interlocked::Read(%(this->m_StopMesh))
{
this->MakeCleanup();
MessageBox(NULL,aMessage,L"Test",NULL);
}
}
}
P.S.: Can you post the code that actually processes the data and checks the variable(I don't mean your full meshes calculations method, just its main stages and elements)?
EDIT: AT LEAST IT'S CLEAR WHAT THE SYSTEM IS ABOUT
It is possible that your child processes are just not exterminated quick enough. Read this SO thread about process killing.
P.S.: And edit your question to more clearly describe your system and problem. It is difficult to get the right answer to a wrong or incomplete question.
Try putting volatile before the field m_StopMesh:
volatile BOOL m_StopMesh;
I launched the c++ process using a thread and it worked fine.
If you want to communicate across process boundaries, you will need to use some sort of cross-process communication.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365574(v=vs.85).aspx
I find Named Pipes convenient and easy to use.
UPDATE
Your comment clarifies that the C++ code is running in-process.
I would suggest a ManualResetEvent. For a great overview of thread synchronization (and threads in general) check out http://www.albahari.com/threading/

How to enable two different C# applications accessing the same directory in a continuous thread?

I have the same BackgroundWorker code piece in two simultaneously running applications. Will this code avoid the problem of same resource getting access by two processes and run smoothly?
void bw_DoWork(object sender, DoWorkEventArgs e)
{
bool flag = false;
System.Threading.Thread.Sleep(1000);
while (flag.Equals(false))
{
string dir = #"C:\ProgramData\Msgs";
try
{
if (Directory.GetFiles(smsdir).Length > 0)
{
flag = true;
}
}
catch (Exception exc)
{
Logger.Log("Dir Access Exception: " + exc.Message);
System.Threading.Thread.Sleep(10);
}
}
On one level, depending on what you're doing, there's nothing wrong with having multiple applications accessing the same directory or file. If it's just read access, then by all means, both can access it at once.
If you've got identical code in multiple applications, then a Boolean isn't going to cut it for synchronization, no matter what you do: Each application has its own copy of the Boolean, and cannot modify the other.
For cross application synhronization, I'd use the Mutex class. There's a constructor that takes a string parameter, specifying the name of the Mutex. Mutex names are unique across all of Windows, not just your application. You can do Mutex m = new Mutex(false, "MySpecialMutex"); in two different applications, and each object will be referring to the same thing.
No, it won't solve the issue because setting the boolean's value and checking it is not an atomic function and is thus not thread safe. You have to use either a Mutex or a Monitor object.
Check this link for more info: Monitor vs Mutex in c#
No, it will not -- at least, the code you have pasted will not accomplish any sort of meaningful process synchronization.
If you want a more detailed and helpful answer, you are going to need to be more specific about what you are doing.
You must come up with some kind of cross-process synchronization scheme - any locking mechanism you use in that code is irrelevant if you're trying to prevent collisions between two processes as opposed to two threads running on the same process.
A good way to do locking across processes like this is to use a file. First process in creates a file and opens it with exclusive access, and then deletes it when its done. The second process in will either see that the file exists and have to wait till it doesn't or it will fail when attempting to open the file exclusively.
no, 'flag' is local to the scope of the method, which is local to the scope of the thread. In other words, it will also equal false.
This is what the lock function is for. Use it like this
In your class, declare a private object called gothread.
in your method write it like this
lock(gothread)
{
// put your code in here, one thread will not be able to enter when another thread is already
// in here
}

NHibernate Concurrency problem

I have a S#arp Architecture app that implements a lightweight queue-processing thing whereby various threads pull entities from a list and set their status to mark the fact that processing has started on those items.
Despite wrapping the start-processing bit in explicit transactions and using a C# lock(), I still get them starting at the same time sometimes.
Do I regret not using MSMQ ... well, yeah, but now this concurrency behaviour has got me baffled. Evidently there's something that I don't understand about NHibernate transactions and flushing. Can you help me out?
Here's the relevant bits of code:
private static object m_lock = new object();
private bool AbleToStartProcessing(int thingId)
{
bool able = false;
try
{
lock (m_lock)
{
this.thingRepository.DbContext.BeginTransaction();
var thing = this.thingRepository.Get(thingId);
if (thing.Status == ThingStatusEnum.PreProcessing)
{
able = true;
thing.Status = ThingStatusEnum.Processing;
}
else
{
logger.DebugFormat("Not able to start processing {0} because status is {1}",
thingId, thing.Status.ToString());
}
this.thingRepository.DbContext.CommitTransaction();
}
}
catch (Exception ex)
{
this.thingRepository.DbContext.RollbackTransaction();
throw ex;
}
if (able)
logger.DebugFormat("Starting processing of {0}",
thingId);
return able;
}
I would have expected this to guarantee that only one thread could change the status of a 'thing' at one time, but I get this in my logs pretty regularly:
2011-05-18 18:41:23,557 thread41 DEBUG src:MyApp.Blah.ThingJob - Starting processing of 78090
2011-05-18 18:41:23,557 thread51 DEBUG src:MyApp.Blah.ThingJob - Starting processing of 78090
.. and then both threads try and operate on the same thing and create a mess.
What am I missing? Thanks.
edit: changed code to reflect how my logging works in the real version
Setup concurrency in your NHibernate mappings, this post should help you get started.
http://ayende.com/blog/3946/nhibernate-mapping-concurrency
i think you are just crossed up on the status you are using to set that you are processing and to check that you are already processing. first one in sets ThingStatusEnum.Processing, but the next guy is checking for something different - ThingStatusEnum.PreProcessing. because ThingStatusEnum.Processing != ThingStatusEnum.PreProcessing, your locking means two threads are not

RasConnectionNotification after computer resumes from sleep

I've got a project called DotRas on CodePlex that exposes a component called RasConnectionWatcher which uses the RasConnectionNotification Win32 API to receive notifications when connections on a machine change. One of my users recently brought to my attention that if the machine comes out of sleep mode, and attempts to redial the connection, the connection goes into a loop indicating the connection is already being dialed even though it isn't. This loop will not end until the application is restarted, even if done through a synchronous call which all values on the structs are unique for that specific call, and none of it is retained once the call completes.
I've done as much as I can to fix the problem, but I fear the problem is something I've done with the RasConnectionNotification API and using ThreadPool.RegisterWaitForSingleObject which might be blocking something else in Windows.
The below method is used to register 1 of the 4 change types the API supports, and the handle to associate with it to monitor. During runtime, the below method would be called 4 times during initialization to register all 4 change types.
private void Register(NativeMethods.RASCN changeType, RasHandle handle)
{
AutoResetEvent waitObject = new AutoResetEvent(false);
int ret = SafeNativeMethods.Instance.RegisterConnectionNotification(handle, waitObject.SafeWaitHandle, changeType);
if (ret == NativeMethods.SUCCESS)
{
RasConnectionWatcherStateObject stateObject = new RasConnectionWatcherStateObject(changeType);
stateObject.WaitObject = waitObject;
stateObject.WaitHandle = ThreadPool.RegisterWaitForSingleObject(waitObject, new WaitOrTimerCallback(this.ConnectionStateChanged), stateObject, Timeout.Infinite, false);
this._stateObjects.Add(stateObject);
}
}
The event passed into the API gets signaled when Windows detects a change in the connections on the machine. The callback used just takes the change type registered from the state object and then processes it to determine exactly what changed.
private void ConnectionStateChanged(object obj, bool timedOut)
{
lock (this.lockObject)
{
if (this.EnableRaisingEvents)
{
try
{
// Retrieve the active connections to compare against the last state that was checked.
ReadOnlyCollection<RasConnection> connections = RasConnection.GetActiveConnections();
RasConnection connection = null;
switch (((RasConnectionWatcherStateObject)obj).ChangeType)
{
case NativeMethods.RASCN.Disconnection:
connection = FindEntry(this._lastState, connections);
if (connection != null)
{
this.OnDisconnected(new RasConnectionEventArgs(connection));
}
if (this.Handle != null)
{
// The handle that was being monitored has been disconnected.
this.Handle = null;
}
this._lastState = connections;
break;
}
}
catch (Exception ex)
{
this.OnError(new System.IO.ErrorEventArgs(ex));
}
}
}
}
}
Everything works perfectly, other than when the machine comes out of sleep. Now the strange thing is when this happens, if a MessageBox is displayed (even for 1 ms and closed by using SendMessage) it will work. I can only imagine something I've done is blocking something else in Windows so that it can't continue processing while the event is being processed by the component.
I've stripped down a lot of the code here, the full source can be found at:
http://dotras.codeplex.com/SourceControl/changeset/view/68525#1344960
I've come for help from people much smarter than myself, I'm outside of my comfort zone trying to fix this problem, any assistance would be greatly appreciated!
Thanks! - Jeff
After a lot of effort, I tracked down the problem. Thankfully it wasn't a blocking issue in Windows.
For those curious, basically once the machine came out of sleep the developer was attempting to immediately dial a connection (via the Disconnected event). Since the network interfaces hadn't finished initializing, an error was returned and the connection handle was not being closed. Any attempts to close the connection would throw an error indicating the connection was already closed, even though it wasn't. Since the handle was left open, any subsequent attempts to dial the connection would cause an actual error.
I just had to make an adjustment in the HangUp code to hide the error thrown when a connection is closed that has already been closed.

How can I create a System Mutex in C#

How can I create a system/multiprocess Mutex to co-ordinate multiple processes using the same unmanaged resource.
Background:
I've written a procedure that uses a File printer, which can only be used by one process at a time. If I wanted to use it on multiple programs running on the computer, I'd need a way to synchronize this across the system.
You can use the System.Threading.Mutex class, which has an OpenExisting method to open a named system mutex.
That doesn't answer the question:
How can I create a system/multiprocess Mutex
To create a system-wide mutex, call the System.Threading.Mutex constructor that takes a string as an argument. This is also known as a 'named' mutex. To see if it exists, I can't seem to find a more graceful method than try catch:
System.Threading.Mutex _mutey = null;
try
{
_mutey = System.Threading.Mutex.OpenExisting("mutex_name");
//we got Mutey and can try to obtain a lock by waitone
_mutey.WaitOne();
}
catch
{
//the specified mutex doesn't exist, we should create it
_mutey = new System.Threading.Mutex("mutex_name"); //these names need to match.
}
Now, to be a good programmer, you need to, when you end the program, release this mutex
_mutey.ReleaseMutex();
or, you can leave it in which case it will be called 'abandoned' when your thread exits, and will allow another process to create it.
[EDIT]
As a side note to the last sentence describing the mutex that is abandoned, when another thread acquires the mutex, the exception System.Threading.AbandonedMutexException will be thrown telling him it was found in the abandoned state.
[EDIT TWO]
I'm not sure why I answered the question that way years ago; there is (and was) a constructor overload that is much better at checking for an existing mutex. In fact, the code I gave seems to have a race condition! (And shame on you all for not correcting me! :-P )
Here's the race condition: Imagine two processes, they both try to open the existing mutex at the same time, and both get to the catch section of code. Then, one of the processes creates the mutex and lives happily ever after. The other process, however, tries to create the mutex, but this time it's already created! This checking/creating of a mutex needs to be atomic.
http://msdn.microsoft.com/en-us/library/bwe34f1k(v=vs.90).aspx
So...
var requestInitialOwnership = false;
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership,
"MyMutex", out mutexWasCreated);
I think the trick here is that it appears that you have an option that you don't actually have (looks like a design flaw to me). You sometimes can't tell if you own the mutex if you send true for requestInitialOwnership. If you pass true and it appears that your call created the mutex, then obviously you own it (confirmed by documentation). If you pass true and your call did not create the mutex, all you know is that the mutex was already created, you don't know if some other process or thread which perhaps created the mutex currently owns the mutex. So, you have to WaitOne to make sure you have it. But then, how many Releases do you do? If some other process owned the mutex when you got it, then only your explicit call to WaitOne needs to be Released. If your call to the constructor caused you to own the mutex, and you called WaitOne explicitly, you'll need two Releases.
I'll put these words into code:
var requestInitialOwnership = true; /*This appears to be a mistake.*/
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership,
"MyMutex", out mutexWasCreated);
if ( !mutexWasCreated )
{
bool calledWaitOne = false;
if ( ! iOwnMutex(m) ) /*I don't know of a method like this*/
{
calledWaitOne = true;
m.WaitOne();
}
doWorkWhileHoldingMutex();
m.Release();
if ( calledWaitOne )
{
m.Release();
}
}
Since I don't see a way to test whether you currently own the mutex, I will strongly recommend that you pass false to the constructor so that you know that you don't own the mutex, and you know how many times to call Release.
You can use the System.Threading.Mutex class, which has an OpenExisting method to open a named system mutex.
I have not had good luck using the System Mutex described above using Mono under Linux. I'm probably just doing something simple wrong but the following works well and cleans up nicely if the process exits unexpectedly (kill -9 ). Would would be interested to hear comments or critisisms.
class SocketMutex{
private Socket _sock;
private IPEndPoint _ep;
public SocketMutex(){
_ep = new IPEndPoint(IPAddress.Parse( "127.0.0.1" ), 7177);
_sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_sock.ExclusiveAddressUse = true; // most critical if you want this to be a system wide mutex
}
public bool GetLock(){
try{
_sock.Bind(_ep); // 'SocketException: Address already in use'
}catch(SocketException se){
Console.Error.WriteLine ("SocketMutex Exception: " se.Message);
return false;
}
return true;
}
}

Categories