469,927 Members | 1,312 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,927 developers. It's quick & easy.

Mutex and single instance console app ?

PL

I simply cannot get this to work with my current project, if I create a test
project
with only the code below it works fine but in my real app it still allows
two instances.

using System;
using System.Threading;

namespace MutexTest
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Mutex appMutex = new Mutex(false, "Application");
if(appMutex.WaitOne(0, false))
{
System.Console.WriteLine("Running");
System.Console.ReadLine();
}
else
{
System.Console.WriteLine("App already running !");
}
}
}
}

The only difference between this test and my app is that I have more
code where I print the "Running" message, no other difference, still
it doesn't work !

I've read numerous other threads saying similar things but no solutions.
Could anyone shed some light as to why this does not work ?

Thank you
PL.
Nov 22 '05 #1
4 3594
PL

This is amazing, I solved it by putting the appMutex variable outside main
and make it static, now it works as expected.

I assume it's because somehow the mutex is garbage collected and therefore
released before it should be.

This seems like a bug to me, I would assume the compiler does some strange
optimization here since it seem to work with the local variable in debug
mode.

PL.

"PL" <pb****@yahoo.se> skrev i meddelandet
news:uC**************@TK2MSFTNGP12.phx.gbl...

I simply cannot get this to work with my current project, if I create a
test project
with only the code below it works fine but in my real app it still allows
two instances.

using System;
using System.Threading;

namespace MutexTest
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Mutex appMutex = new Mutex(false, "Application");
if(appMutex.WaitOne(0, false))
{
System.Console.WriteLine("Running");
System.Console.ReadLine();
}
else
{
System.Console.WriteLine("App already running !");
}
}
}
}

The only difference between this test and my app is that I have more
code where I print the "Running" message, no other difference, still
it doesn't work !

I've read numerous other threads saying similar things but no solutions.
Could anyone shed some light as to why this does not work ?

Thank you
PL.

Nov 22 '05 #2
No, this is not a bug in .NET, it's a "users bug". The JIT is free to mark
objects that are no longer referenced in the code path eligible for GC, the
fact that the underlying handle is a system wide kernel object that should
be kept for the duration of the program is not the JIT business.
To prevent premature collection of the Mutex you could wrap your code in a
using block (yes, Mutex derives from a Disposable), this is more elegant
than using a static.

using(System.Threading.Mutex m = new System.Threading.Mutex(true,
"YourNameHere"))
{
// Your code here
} // Done with the Mutex, the handle can be released

Willy.

"PL" <pb****@yahoo.se> wrote in message
news:uC**************@TK2MSFTNGP12.phx.gbl...

I simply cannot get this to work with my current project, if I create a
test project
with only the code below it works fine but in my real app it still allows
two instances.

using System;
using System.Threading;

namespace MutexTest
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Mutex appMutex = new Mutex(false, "Application");
if(appMutex.WaitOne(0, false))
{
System.Console.WriteLine("Running");
System.Console.ReadLine();
}
else
{
System.Console.WriteLine("App already running !");
}
}
}
}

The only difference between this test and my app is that I have more
code where I print the "Running" message, no other difference, still
it doesn't work !

I've read numerous other threads saying similar things but no solutions.
Could anyone shed some light as to why this does not work ?

Thank you
PL.

Nov 22 '05 #3
PL

Thank you, the using block worked fine as well and is as you say more
elegant.

I guess what confuses me here is the definition of "not referenced", if I
have a local
variable in Main that do not change you would think it stays referenced
during the
whole lifetime of the program but apparently not.

I guess I need to read up on the garbage collector.

Considering all the examples I found on the net on how to do this that
didn't use a static variable,
a using block or gc.keepalive it seems to me like only more memory intensive
programs experience
this issue which makes it somewhat dangerous.

PL.
"Willy Denoyette [MVP]" <wi*************@pandora.be> skrev i meddelandet
news:eH**************@TK2MSFTNGP15.phx.gbl...
No, this is not a bug in .NET, it's a "users bug". The JIT is free to mark
objects that are no longer referenced in the code path eligible for GC,
the fact that the underlying handle is a system wide kernel object that
should be kept for the duration of the program is not the JIT business.
To prevent premature collection of the Mutex you could wrap your code in a
using block (yes, Mutex derives from a Disposable), this is more elegant
than using a static.

using(System.Threading.Mutex m = new System.Threading.Mutex(true,
"YourNameHere"))
{
// Your code here
} // Done with the Mutex, the handle can be released

Willy.

Nov 22 '05 #4

"PL" <pb****@yahoo.se> wrote in message
news:eP**************@TK2MSFTNGP10.phx.gbl...

Thank you, the using block worked fine as well and is as you say more
elegant.

I guess what confuses me here is the definition of "not referenced", if I
have a local
variable in Main that do not change you would think it stays referenced
during the
whole lifetime of the program but apparently not.


This is something to watch out for. A local variable holding a reference to
an object in the managed heap, will be set to null by the JIT compiler
(running in non-debug mode) when it's no longer used in the scope of the
method. Now in the case of a Mutex, the underlying OS handle will only be
released when the finalizer comes along, which can be a long time after the
reference was null'ed. To take control of the lifetime of such an unmanaged
resource you should adopt the disposing pattern and wrap your code in a
using block, just like I've done with the using block.

Willy.
Nov 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Martin Maat | last post: by
20 posts views Thread by Michael A. Covington | last post: by
2 posts views Thread by tony.newsgrps | last post: by
1 post views Thread by cold80 | last post: by
2 posts views Thread by =?Utf-8?B?Q2F2ZXk=?= | last post: by
2 posts views Thread by cj | last post: by
11 posts views Thread by Lamont Sanford | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.