[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework

Problem with mutex in release mode

Ashutosh

9/30/2008 5:44:00 AM

Hi,
I have this code...it works fine in debug mode but not in release mode...

bool bOwnInitially = true;
bool bCreated;
Mutex m = new Mutex(bOwnInitially,
"2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
if (!(bCreated && bOwnInitially))
{
MessageBox.Show(Resources.InstanceAlreadyRunning, "My
App", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}

Can someone please tell me what's wrong here?

Regards,
Ashutosh
11 Answers

jialge

9/30/2008 9:11:00 AM

0

Hello Ashutosh

If I understand it rightly, this piece of code is used to enforce a rule
that only one instance of the app process is running. You mentioned that
the code runs fine in debug mode but not in release mode, it's most likely
be caused by the optimization of JIT in release mode. JIT may optimize some
codes or remove some variables that are not used afterwards when the
optimization switch is on. How do you call this piece of code? What's the
output of release mode on your side? I just tested it in a simple winform
project:

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool bOwnInitially = true;
bool bCreated;
Mutex m = new Mutex(bOwnInitially,
"2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
if (!(bCreated && bOwnInitially))
{
MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}

The test project runs as expected (only one instance of the app is allowed)
in both debug and release mode.

Please let me know how you called the code and I will try to find out the
problem. A reproducible project will be very helpful.

==== Additional Resources ====
Single Process Instance Object
http://www.codeproject.com/KB/cs/cssingpr...


Regards,
Jialiang Ge (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================



Marc Gravell

9/30/2008 9:42:00 AM

0

You need a GC.KeepAlive(m); at the bottom of the code.

Essentially, the optimisations mean that m can legally be garbage
collected at any point after creation (since you don't ever re-read m).
The GC.KeepAlive(m) does nothing except provide an opaque read of the
variable that can't be optimised away.

Marc

Ashutosh

9/30/2008 11:16:00 AM

0

Thanks for input...

Yes, the object was getting garbage collected and even GC.KeepAlive
didn't solve the issue...

So, I made a root object point to it...the root from which the GC starts
creating the reference tree...

Thanks!!
Ashutosh

Marc Gravell wrote:
> You need a GC.KeepAlive(m); at the bottom of the code.
>
> Essentially, the optimisations mean that m can legally be garbage
> collected at any point after creation (since you don't ever re-read
> m). The GC.KeepAlive(m) does nothing except provide an opaque read of
> the variable that can't be optimised away.
>
> Marc

Ashutosh

9/30/2008 11:17:00 AM

0

I was doing exactly the same as you posted....it was getting garbage
collected and even GC.KeepAlive was not solving the issue...
So, I made a root object point to it...
The issue is resolved...

Thanks
Ashutosh

Jialiang Ge [MSFT] wrote:
> Hello Ashutosh
>
> If I understand it rightly, this piece of code is used to enforce a rule
> that only one instance of the app process is running. You mentioned that
> the code runs fine in debug mode but not in release mode, it's most likely
> be caused by the optimization of JIT in release mode. JIT may optimize some
> codes or remove some variables that are not used afterwards when the
> optimization switch is on. How do you call this piece of code? What's the
> output of release mode on your side? I just tested it in a simple winform
> project:
>
> /// <summary>
> /// The main entry point for the application.
> /// </summary>
> [STAThread]
> static void Main()
> {
> bool bOwnInitially = true;
> bool bCreated;
> Mutex m = new Mutex(bOwnInitially,
> "2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
> if (!(bCreated && bOwnInitially))
> {
> MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
> MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
> return;
> }
>
> Application.EnableVisualStyles();
> Application.SetCompatibleTextRenderingDefault(false);
> Application.Run(new Form1());
> }
>
> The test project runs as expected (only one instance of the app is allowed)
> in both debug and release mode.
>
> Please let me know how you called the code and I will try to find out the
> problem. A reproducible project will be very helpful.
>
> ==== Additional Resources ====
> Single Process Instance Object
> http://www.codeproject.com/KB/cs/cssingpr...
>
>
> Regards,
> Jialiang Ge (jialge@online.microsoft.com, remove 'online.')
> Microsoft Online Community Support
>
> =================================================
> Delighting our customers is our #1 priority. We welcome your comments and
> suggestions about how we can improve the support we provide to you. Please
> feel free to let my manager know what you think of the level of service
> provided. You can send feedback directly to my manager at:
> msdnmg@microsoft.com.
>
> This posting is provided "AS IS" with no warranties, and confers no rights.
> =================================================
>
>
>
>

Jon Skeet

9/30/2008 5:19:00 PM

0

Ashutosh <smbs-msdn@nospam.nospam> wrote:
> Thanks for input...
>
> Yes, the object was getting garbage collected and even GC.KeepAlive
> didn't solve the issue...

I doubt that very much. GC.KeepAlive works perfectly well, when used
properly. How did you try to use it?

--
Jon Skeet - <skeet@pobox.com>
Web site: http://www.pobox....
Blog: http://www.msmvps.com...
C# in Depth: http://csharpi...

jialge

10/1/2008 2:35:00 AM

0

Thank you Jon and Mark for finding out the reason. I can reproduce the
problem now with this piece of code: (add GC.Collect())

[STAThread]
static void Main()
{
bool bOwnInitially = true;
bool bCreated;
Mutex m = new Mutex(bOwnInitially,
"2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
if (!(bCreated && bOwnInitially))
{
MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}

GC.Collect();

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}

As for the solution, both GC.KeepAlive and GCHandle.Alloc should help if
they are used properly. For example:

=== GC.KeepAlive ===

[STAThread]
static void Main()
{
bool bOwnInitially = true;
bool bCreated;
Mutex m = new Mutex(bOwnInitially,
"2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
if (!(bCreated && bOwnInitially))
{
MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());

GC.KeepAlive(m); // keep the obj m alive in main.
}

=== GCHandle.Alloc ===

[STAThread]
static void Main()
{
bool bOwnInitially = true;
bool bCreated;
Mutex m = new Mutex(bOwnInitially,
"2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);

GCHandle handle = GCHandle.Alloc(m); // allocate gc handle

if (!(bCreated && bOwnInitially))
{
MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());

handle.Free(); // release gc handle.
}

Regards,
Jialiang Ge (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================

Ashutosh

10/1/2008 3:03:00 AM

0

I added GC.KeepAlive just before Application.EnableVisualStyles()
I will try again and update.
Thank you all for your help.

Regard,
Ashutosh

Jialiang Ge [MSFT] wrote:
> Thank you Jon and Mark for finding out the reason. I can reproduce the
> problem now with this piece of code: (add GC.Collect())
>
> [STAThread]
> static void Main()
> {
> bool bOwnInitially = true;
> bool bCreated;
> Mutex m = new Mutex(bOwnInitially,
> "2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
> if (!(bCreated && bOwnInitially))
> {
> MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
> MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
> return;
> }
>
> GC.Collect();
>
> Application.EnableVisualStyles();
> Application.SetCompatibleTextRenderingDefault(false);
> Application.Run(new Form1());
> }
>
> As for the solution, both GC.KeepAlive and GCHandle.Alloc should help if
> they are used properly. For example:
>
> === GC.KeepAlive ===
>
> [STAThread]
> static void Main()
> {
> bool bOwnInitially = true;
> bool bCreated;
> Mutex m = new Mutex(bOwnInitially,
> "2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
> if (!(bCreated && bOwnInitially))
> {
> MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
> MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
> return;
> }
>
> Application.EnableVisualStyles();
> Application.SetCompatibleTextRenderingDefault(false);
> Application.Run(new Form1());
>
> GC.KeepAlive(m); // keep the obj m alive in main.
> }
>
> === GCHandle.Alloc ===
>
> [STAThread]
> static void Main()
> {
> bool bOwnInitially = true;
> bool bCreated;
> Mutex m = new Mutex(bOwnInitially,
> "2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
>
> GCHandle handle = GCHandle.Alloc(m); // allocate gc handle
>
> if (!(bCreated && bOwnInitially))
> {
> MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
> MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
> return;
> }
>
> Application.EnableVisualStyles();
> Application.SetCompatibleTextRenderingDefault(false);
> Application.Run(new Form1());
>
> handle.Free(); // release gc handle.
> }
>
> Regards,
> Jialiang Ge (jialge@online.microsoft.com, remove 'online.')
> Microsoft Online Community Support
>
> =================================================
> Delighting our customers is our #1 priority. We welcome your comments and
> suggestions about how we can improve the support we provide to you. Please
> feel free to let my manager know what you think of the level of service
> provided. You can send feedback directly to my manager at:
> msdnmg@microsoft.com.
>
> This posting is provided "AS IS" with no warranties, and confers no rights.
> =================================================
>
>

Jon Skeet

10/1/2008 5:30:00 AM

0

Ashutosh <smbs-msdn@nospam.nospam> wrote:
> I added GC.KeepAlive just before Application.EnableVisualStyles()
> I will try again and update.

No, it needs to be right at the end - otherwise the mutex can be
collected while your app is running, which wil let another instance of
the app be created. The whole point is to keep it alive for the entire
duration of the app.

--
Jon Skeet - <skeet@pobox.com>
Web site: http://www.pobox....
Blog: http://www.msmvps.com...
C# in Depth: http://csharpi...

Jim Rand

10/1/2008 1:00:00 PM

0

Why don't you create a singleton class that creates a reference to the
Mutex? That way, it won't go out of scope.


""Jialiang Ge [MSFT]"" <jialge@online.microsoft.com> wrote in message
news:UmLSF52IJHA.1652@TK2MSFTNGHUB02.phx.gbl...
> Thank you Jon and Mark for finding out the reason. I can reproduce the
> problem now with this piece of code: (add GC.Collect())
>
> [STAThread]
> static void Main()
> {
> bool bOwnInitially = true;
> bool bCreated;
> Mutex m = new Mutex(bOwnInitially,
> "2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
> if (!(bCreated && bOwnInitially))
> {
> MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
> MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
> return;
> }
>
> GC.Collect();
>
> Application.EnableVisualStyles();
> Application.SetCompatibleTextRenderingDefault(false);
> Application.Run(new Form1());
> }
>
> As for the solution, both GC.KeepAlive and GCHandle.Alloc should help if
> they are used properly. For example:
>
> === GC.KeepAlive ===
>
> [STAThread]
> static void Main()
> {
> bool bOwnInitially = true;
> bool bCreated;
> Mutex m = new Mutex(bOwnInitially,
> "2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
> if (!(bCreated && bOwnInitially))
> {
> MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
> MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
> return;
> }
>
> Application.EnableVisualStyles();
> Application.SetCompatibleTextRenderingDefault(false);
> Application.Run(new Form1());
>
> GC.KeepAlive(m); // keep the obj m alive in main.
> }
>
> === GCHandle.Alloc ===
>
> [STAThread]
> static void Main()
> {
> bool bOwnInitially = true;
> bool bCreated;
> Mutex m = new Mutex(bOwnInitially,
> "2ba3dbae-eb22-4712-81e1-638a10a33ab3", out bCreated);
>
> GCHandle handle = GCHandle.Alloc(m); // allocate gc handle
>
> if (!(bCreated && bOwnInitially))
> {
> MessageBox.Show(Resources.InstanceAlreadyRunning, "My App",
> MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
> return;
> }
>
> Application.EnableVisualStyles();
> Application.SetCompatibleTextRenderingDefault(false);
> Application.Run(new Form1());
>
> handle.Free(); // release gc handle.
> }
>
> Regards,
> Jialiang Ge (jialge@online.microsoft.com, remove 'online.')
> Microsoft Online Community Support
>
> =================================================
> Delighting our customers is our #1 priority. We welcome your comments and
> suggestions about how we can improve the support we provide to you. Please
> feel free to let my manager know what you think of the level of service
> provided. You can send feedback directly to my manager at:
> msdnmg@microsoft.com.
>
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
> =================================================
>


Jon Skeet

10/1/2008 4:52:00 PM

0


Jim Rand <jimrand@ix.netcom.com> wrote:
> Why don't you create a singleton class that creates a reference to the
> Mutex? That way, it won't go out of scope.

A single call to GC.KeepAlive seems a bit simpler to me :)

--
Jon Skeet - <skeet@pobox.com>
Web site: http://www.pobox....
Blog: http://www.msmvps.com...
C# in Depth: http://csharpi...