Problem with named mutex

C

cold80

I'm trying to check in my application if another instance of it is
already running. I found many code snippets on the net that make use of
a named mutex to do this check, but I can't make it work on visual
basic. Actually, it works sometimes and sometimes not. The code I'm
trying is:

Namespace WindowsApplication2
Public Class Form1
Inherits Form

Public Sub New()

End Sub

Private Shared appGuid As String = "uniquekeyonmymachine"

Public Shared Sub Main()
Dim m As Mutex

m = New Mutex(False, appGuid)
If m.WaitOne(0, False) = False Then
MessageBox.Show("Instance already running")
Return
End If

Application.Run(New Form1())
End Sub
End Class
End Namespace

Using this different piece of code in C# (and the keyword "using") the
method seems to work without problems (and always)

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

static string appGuid = "uniquekeyonmymachine";

[STAThread]
static void Main()
{
using (Mutex mutex = new Mutex(false, appGuid))
{
if (!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance already running");
return;
}

Application.Run(new Form1());
}

}
}

}

What do you think can be the problem? Some people suggested that the
Garbage Collector could have destroy the mutex object before I tryied
to run another instance of the program, but the call to Application.Run
is a blocking one, isn't it? So the local object m should live until
the end of the program, right?

Thank you in advance for your help.

Cold
 
J

Jon Skeet [C# MVP]

cold80 said:
I'm trying to check in my application if another instance of it is
already running. I found many code snippets on the net that make use of
a named mutex to do this check, but I can't make it work on visual
basic. Actually, it works sometimes and sometimes not. The code I'm
trying is:

I suspect that the problem is that your mutex is being finalized while
your application is running, as others have suggested. The garbage
collector can finalize and release objects when they've last been used
- it doesn't have to wait until they "fall out of scope".

If you put either m.Dispose() or C.KeepAlive(m) fter the call to
Application.Run (new Form1()) I think you'll find that solves the
problem.

The call to Dispose is the equivalent to what the C# code is doing, by
the way (except that it does it in a finally block, effectively).

By the way, you don't need to call WaitOne. If you use the form of the
Mutex constructor which has a boolean out parameter as its last
parameter, you can get the information just from that. In C#:

bool firstInstance;
Mutex mutex = new Mutex(false, "Local\\"+someUniqueName,
out firstInstance);
 
C

cold80

Thank you for your help, now it is working. Actually I read the same
article you are referring to and I was a little confused about the
solution they proposed. I thought that the GC couldn't touch my objects
before they went out of scope...but now you're saying that it can, so
the pieces are coming to the right place. But how can the GC know that
a specific object is not used anymore, so it can destroy it? Or the
destruction is inserted by the compiler whenever it realizes the
there's no more code that use a specific object? I would like to
understand this better before doing some trivial mistake...Do you have
some articles where I can refer to?

Thank you a lot

Cold
 
J

Jon Skeet [C# MVP]

cold80 said:
Thank you for your help, now it is working. Actually I read the same
article you are referring to and I was a little confused about the
solution they proposed. I thought that the GC couldn't touch my objects
before they went out of scope...but now you're saying that it can, so
the pieces are coming to the right place. But how can the GC know that
a specific object is not used anymore, so it can destroy it? Or the
destruction is inserted by the compiler whenever it realizes the
there's no more code that use a specific object? I would like to
understand this better before doing some trivial mistake...Do you have
some articles where I can refer to?

No, the compiler doesn't tell anything to finalize/GC the object - it
can't tell whether or not it's in use somewhere else. What it *can* do
is mark the region where the *variable* is available. It knows the last
time the variable is read, and as far as the GC is concerned, the
variable doesn't exist after that point.
 

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