ReleaseMutex problem

S

Steve Barnett

I've tried to create a "single instance" application using a mutex and, as
far as I can see, it's functioning right up until I close the application.
When I try to release the mutex, I get an ApplicationException with the
explanation: "Object synchronisation method was called from an
unsynchronised block of code".

I'm sure this tells me exactly how to fix it... well, it would if I
understood it. Can anyone suggest where I'm going wrong? (By the way, if I
don't release the Mutex, everything works perfectly well - I'm just trying
to do things properly).

I've tried surrounding the code to obtain and release the Mutex with a
lock() statement, but that made no difference. The code is shown below...

Thanks
Steve

namespace SingleInstance
{
static class Program
{
private static Mutex appMutex = null;

[STAThread]
static void Main()
{
bool newMutexCreated = false;
string mutexName = "Local\\IPM4Mutex";

try
{
appMutex = new Mutex(false, mutexName, out
newMutexCreated);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
Application.Exit();
}

if (newMutexCreated == true)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
// We're not the first instalce of this program. Tell the
other instance
// what our command line was...
SingleAppServices SendCommandLine = new SingleAppServices();
SendCommandLine.Channels.Add("CommandLineParms");
SendCommandLine.Channels["CommandLineParms"].Send(String.Join("
", System.Environment.GetCommandLineArgs()));

// Now close this form - we don't need it any more
Application.Exit();
}

GC.KeepAlive(appMutex);

// ********************** This is where
// ********************** I get the exception.
appMutex.ReleaseMutex();

}
}
}
 
S

Steve Barnett

I remembered your response and I tried using WindowsFormsApplicationBase but
it invariably failed with an access violation.

I even tried a sample app I downloaded from CodeProject and that failed with
the same error. I then downloaded a VB.Net app that used this mechanism (on
the basis that it might be an issue between C# and VB) and, guess what, it
had an access violation. I've looked around the net a little and it seems
that there is some sort of problem with the socket libraries and how they
interact with other applications (non-specific but it seems Norton AV is an
issue).

So I gave up on the basis that it's unstable and not worth the risk. I'm now
using a Mutex and some code I found on vbaccelerator.com that allows me to
send data to another app via the WM_COPYDATA message. As it turned out, this
is also useful for sending data within the app - now all I need is a reason
want to do that.

Thanks
Steve


Nicholas Paldino said:
Steve,

If you are using .NET 2.0, there is a much simpler solution available
to you. I posted a response about it a while ago, and you can see it
here:

http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/msg/07128f9ddd957ada

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Steve Barnett said:
I've tried to create a "single instance" application using a mutex and,
as far as I can see, it's functioning right up until I close the
application. When I try to release the mutex, I get an
ApplicationException with the explanation: "Object synchronisation method
was called from an unsynchronised block of code".

I'm sure this tells me exactly how to fix it... well, it would if I
understood it. Can anyone suggest where I'm going wrong? (By the way, if
I don't release the Mutex, everything works perfectly well - I'm just
trying to do things properly).

I've tried surrounding the code to obtain and release the Mutex with a
lock() statement, but that made no difference. The code is shown below...

Thanks
Steve

namespace SingleInstance
{
static class Program
{
private static Mutex appMutex = null;

[STAThread]
static void Main()
{
bool newMutexCreated = false;
string mutexName = "Local\\IPM4Mutex";

try
{
appMutex = new Mutex(false, mutexName, out
newMutexCreated);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
Application.Exit();
}

if (newMutexCreated == true)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
// We're not the first instalce of this program. Tell the
other instance
// what our command line was...
SingleAppServices SendCommandLine = new
SingleAppServices();
SendCommandLine.Channels.Add("CommandLineParms");

SendCommandLine.Channels["CommandLineParms"].Send(String.Join(" ",
System.Environment.GetCommandLineArgs()));

// Now close this form - we don't need it any more
Application.Exit();
}

GC.KeepAlive(appMutex);

// ********************** This is where
// ********************** I get the exception.
appMutex.ReleaseMutex();

}
}
}
 
N

Nicholas Paldino [.NET/C# MVP]

Steve,

Can you show the code, and where the access violation takes place? You
are right that it is most likely the AV, but that does not mean that the
code is unstable, as it is not the responsibility of
WindowsFormsApplicationBase to be aware of AV, but the other way around.

And AFAIK, it doesn't use sockets but a named pipe for communication
between processes (it would be overkill to use sockets).

i

Steve Barnett said:
I remembered your response and I tried using WindowsFormsApplicationBase
but it invariably failed with an access violation.

I even tried a sample app I downloaded from CodeProject and that failed
with the same error. I then downloaded a VB.Net app that used this
mechanism (on the basis that it might be an issue between C# and VB) and,
guess what, it had an access violation. I've looked around the net a
little and it seems that there is some sort of problem with the socket
libraries and how they interact with other applications (non-specific but
it seems Norton AV is an issue).

So I gave up on the basis that it's unstable and not worth the risk. I'm
now using a Mutex and some code I found on vbaccelerator.com that allows
me to send data to another app via the WM_COPYDATA message. As it turned
out, this is also useful for sending data within the app - now all I need
is a reason want to do that.

Thanks
Steve


Nicholas Paldino said:
Steve,

If you are using .NET 2.0, there is a much simpler solution available
to you. I posted a response about it a while ago, and you can see it
here:

http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/msg/07128f9ddd957ada

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Steve Barnett said:
I've tried to create a "single instance" application using a mutex and,
as far as I can see, it's functioning right up until I close the
application. When I try to release the mutex, I get an
ApplicationException with the explanation: "Object synchronisation
method was called from an unsynchronised block of code".

I'm sure this tells me exactly how to fix it... well, it would if I
understood it. Can anyone suggest where I'm going wrong? (By the way, if
I don't release the Mutex, everything works perfectly well - I'm just
trying to do things properly).

I've tried surrounding the code to obtain and release the Mutex with a
lock() statement, but that made no difference. The code is shown
below...

Thanks
Steve

namespace SingleInstance
{
static class Program
{
private static Mutex appMutex = null;

[STAThread]
static void Main()
{
bool newMutexCreated = false;
string mutexName = "Local\\IPM4Mutex";

try
{
appMutex = new Mutex(false, mutexName, out
newMutexCreated);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
Application.Exit();
}

if (newMutexCreated == true)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
// We're not the first instalce of this program. Tell the
other instance
// what our command line was...
SingleAppServices SendCommandLine = new
SingleAppServices();
SendCommandLine.Channels.Add("CommandLineParms");

SendCommandLine.Channels["CommandLineParms"].Send(String.Join(" ",
System.Environment.GetCommandLineArgs()));

// Now close this form - we don't need it any more
Application.Exit();
}

GC.KeepAlive(appMutex);

// ********************** This is where
// ********************** I get the exception.
appMutex.ReleaseMutex();

}
}
}
 
S

Steve Barnett

I took my code from http://www.codeproject.com/csharp/CSSIApp.asp. This was
perfect for what I wanted.

When my code didn't work, I compiled the sample app that the author provided
and still got the access violation. The error itself appears in VS but is
not associated with any specific line of code (i.e. no line is highlighted).
I tried a Try/Catch around the code and it did NOT catch the error.

The specific error you get is:
" at
System.Net.UnsafeNclNativeMethods.OSSOCK.WSAGetOverlappedResult(SafeCloseSocket
socketHandle, IntPtr overlapped, UInt32& bytesTransferred, Boolean wait,
IntPtr ignored)\r\n at
System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32
errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)\r\n at
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32
errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)"

As you'll see from the comments at the bottom of the article, someone else
has had the same problem but no solution was offered by the author. Another
poster suggested the problem was NetLimiter, but I don;'t have that running.
When I checked through Google, I found similar issues, one of which
suggested NAV as the culprit.

I guess the point is that I can't control what my end users will run ion
their PCs and I certainly can't tell them that they must not run specific
packages.

I don't know whether this is a failing of the .Net framework or something
else. All I know is that it does not work on my development machine, so I
can't legitimately give it to a user.

Thanks
Steve


Nicholas Paldino said:
Steve,

Can you show the code, and where the access violation takes place? You
are right that it is most likely the AV, but that does not mean that the
code is unstable, as it is not the responsibility of
WindowsFormsApplicationBase to be aware of AV, but the other way around.

And AFAIK, it doesn't use sockets but a named pipe for communication
between processes (it would be overkill to use sockets).

i

Steve Barnett said:
I remembered your response and I tried using WindowsFormsApplicationBase
but it invariably failed with an access violation.

I even tried a sample app I downloaded from CodeProject and that failed
with the same error. I then downloaded a VB.Net app that used this
mechanism (on the basis that it might be an issue between C# and VB) and,
guess what, it had an access violation. I've looked around the net a
little and it seems that there is some sort of problem with the socket
libraries and how they interact with other applications (non-specific but
it seems Norton AV is an issue).

So I gave up on the basis that it's unstable and not worth the risk. I'm
now using a Mutex and some code I found on vbaccelerator.com that allows
me to send data to another app via the WM_COPYDATA message. As it turned
out, this is also useful for sending data within the app - now all I need
is a reason want to do that.

Thanks
Steve


Nicholas Paldino said:
Steve,

If you are using .NET 2.0, there is a much simpler solution available
to you. I posted a response about it a while ago, and you can see it
here:

http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/msg/07128f9ddd957ada

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I've tried to create a "single instance" application using a mutex and,
as far as I can see, it's functioning right up until I close the
application. When I try to release the mutex, I get an
ApplicationException with the explanation: "Object synchronisation
method was called from an unsynchronised block of code".

I'm sure this tells me exactly how to fix it... well, it would if I
understood it. Can anyone suggest where I'm going wrong? (By the way,
if I don't release the Mutex, everything works perfectly well - I'm
just trying to do things properly).

I've tried surrounding the code to obtain and release the Mutex with a
lock() statement, but that made no difference. The code is shown
below...

Thanks
Steve

namespace SingleInstance
{
static class Program
{
private static Mutex appMutex = null;

[STAThread]
static void Main()
{
bool newMutexCreated = false;
string mutexName = "Local\\IPM4Mutex";

try
{
appMutex = new Mutex(false, mutexName, out
newMutexCreated);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
Application.Exit();
}

if (newMutexCreated == true)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
// We're not the first instalce of this program. Tell
the other instance
// what our command line was...
SingleAppServices SendCommandLine = new
SingleAppServices();
SendCommandLine.Channels.Add("CommandLineParms");

SendCommandLine.Channels["CommandLineParms"].Send(String.Join(" ",
System.Environment.GetCommandLineArgs()));

// Now close this form - we don't need it any more
Application.Exit();
}

GC.KeepAlive(appMutex);

// ********************** This is where
// ********************** I get the exception.
appMutex.ReleaseMutex();

}
}
}
 

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

Similar Threads


Top