Window Application Main() life time?

G

Guest

I wrote some Windows application. in the Main() method of the project I use
Mutex.
I was sure that that mutex will live during all the application run time.
But it appears that the Mutex is CG after a while.

The following code is the code I'm using. I use it to make sure only one
instance of my program is running, but there are cases that the ownership is
obtained although there is already another application like this running:

[STAThread]
static void Main()
{
bool hasOwnership;
System.Threading.Mutex singelLogger = new System.Threading.Mutex(true,
"MyApplication", out hasOwnership);if( ! hasOwnership )
{
MessageBox.Show(null, "The Mutex ownership is taken.\n\n Exiting!", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
Application.Run( new MyAppForm() );
}


How can that be?
 
R

Richard Blewett [DevelopMentor]

The problem is that in release builds the GC is *very* aggressive on what it considers to a dead local variable. The JIT compiler notes the real lifetime of local variables (rather than just their scope) and makes this information available to the GC. So in your code example the variable singelLogger is not used after the line in which it is declared. Therefore, the GC considers this to be a dead local variable beyond this point and as there are no other references to the object the GC will collect it.

You can use the GCHandle class to root the mutex:

[STAThread]
static void Main()
{
bool hasOwnership;
System.Threading.Mutex singelLogger = new System.Threading.Mutex(true, "MyApplication", out hasOwnership);
GCHandle gch = GCHandle.Alloc(singelLogger);

if( ! hasOwnership )
{
MessageBox.Show(null, "The Mutex ownership is taken.\n\n Exiting!", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
Application.Run( new MyAppForm() );
gch.Free();
}

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

I wrote some Windows application. in the Main() method of the project I use
Mutex.
I was sure that that mutex will live during all the application run time.
But it appears that the Mutex is CG after a while.

The following code is the code I'm using. I use it to make sure only one
instance of my program is running, but there are cases that the ownership is
obtained although there is already another application like this running:

[STAThread]
static void Main()
{
bool hasOwnership;
System.Threading.Mutex singelLogger = new System.Threading.Mutex(true,
"MyApplication", out hasOwnership);if( ! hasOwnership )
{
MessageBox.Show(null, "The Mutex ownership is taken.\n\n Exiting!", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
Application.Run( new MyAppForm() );
}


How can that be?
 
R

Richard Blewett [DevelopMentor]

Or of course you could just release the Mutex at the end of the method ;-)

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

The problem is that in release builds the GC is *very* aggressive on what it considers to a dead local variable. The JIT compiler notes the real lifetime of local variables (rather than just their scope) and makes this information available to the GC. So in your code example the variable singelLogger is not used after the line in which it is declared. Therefore, the GC considers this to be a dead local variable beyond this point and as there are no other references to the object the GC will collect it.
 
G

Guest

Well, now we all know that there are several solutions for it.

But we also know that the GC is a "BUG"er that we should be careful off.
 
W

Willy Denoyette [MVP]

Sharon said:
Well, now we all know that there are several solutions for it.

But we also know that the GC is a "BUG"er that we should be careful off.

This has nothing to do with the GC nor is it a bug.
The JITter rightfully decides that the mutex is no longer needed as nothing
in the code path holds a reference to it.
The fact that the underlying system wide OS mutex (an unmanaged resource) is
freed when the finalizer comes along is not the GC's problem, it's yours. So
IMO it's a user program bug.

Willy.
 
G

Guest

Hi Sharon,

You're not calling ReleaseMutex()... Wrap this code in a
try...catch...finally, and call ReleaseMutex() in the finally clause. That
way, the GC can't collect the mutex, since it's not yet out of scope ;o)

-Ernst
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top