473,605 Members | 2,703 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

A mutex puzzle; single instance of application

See:
http://www.ai.uga.edu/mc/SingleInstance.html

While attempting to use a mutex to allow only one instance of my app to run
at a time (Recipe 4.12 in C# Programmer's Cookbook), I found that if the
mutex is in a local variable in Main(), and my program launches any windows
before Application.Run (), it will lose the mutex upon doing so. It
shouldn't, as far as I can see. Moving the mutex variable outside Main()
and making it static eliminates the problem.

Any ideas? Is there a subtle matter of variable scope and extent that I
haven't understood? Does a process lose its mutexes when it launches a
window? Why?

(The mutex variable still exists, and m.Handle has the same value; but
according to ProcessExplorer , the mutex no longer exists. And all of this
happens only for processes launched from Windows, not under the IDE!)

--

Michael A. Covington - Artificial Intelligence Ctr - University of Georgia

"In the core C# language it is simply not possible to have an uninitialized
variable, a 'dangling' pointer, or an expression that indexes an array
beyond its bounds. Whole categories of bugs that routinely plague C and C++
programs are thus eliminated." - A. Hejlsberg, The C# Programming Language
Nov 15 '05 #1
20 6468
Michael A. Covington <lo**@www.covin gtoninnovations .com.for.addres s>
wrote:
See:
http://www.ai.uga.edu/mc/SingleInstance.html

While attempting to use a mutex to allow only one instance of my app to run
at a time (Recipe 4.12 in C# Programmer's Cookbook), I found that if the
mutex is in a local variable in Main(), and my program launches any windows
before Application.Run (), it will lose the mutex upon doing so. It
shouldn't, as far as I can see. Moving the mutex variable outside Main()
and making it static eliminates the problem.

Any ideas? Is there a subtle matter of variable scope and extent that I
haven't understood? Does a process lose its mutexes when it launches a
window? Why?

(The mutex variable still exists, and m.Handle has the same value; but
according to ProcessExplorer , the mutex no longer exists. And all of this
happens only for processes launched from Windows, not under the IDE!)


My guess is that the JIT can notice that the Mutex is no longer
referenced, and thus marks it as available for garbage collection. As a
way of testing this, put the line:

GC.KeepAlive (myMutex);

at the *end* of the Main method.

Let me know if that works, and I'll mention it in the FAQ.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #2
Works for me, could you post your failing Main() method?

Willy.

"Michael A. Covington" <lo**@www.covin gtoninnovations .com.for.addres s> wrote
in message news:OP******** ******@TK2MSFTN GP11.phx.gbl...
See:
http://www.ai.uga.edu/mc/SingleInstance.html

While attempting to use a mutex to allow only one instance of my app to
run
at a time (Recipe 4.12 in C# Programmer's Cookbook), I found that if the
mutex is in a local variable in Main(), and my program launches any
windows
before Application.Run (), it will lose the mutex upon doing so. It
shouldn't, as far as I can see. Moving the mutex variable outside Main()
and making it static eliminates the problem.

Any ideas? Is there a subtle matter of variable scope and extent that I
haven't understood? Does a process lose its mutexes when it launches a
window? Why?

(The mutex variable still exists, and m.Handle has the same value; but
according to ProcessExplorer , the mutex no longer exists. And all of this
happens only for processes launched from Windows, not under the IDE!)

--

Michael A. Covington - Artificial Intelligence Ctr - University of Georgia

"In the core C# language it is simply not possible to have an
uninitialized
variable, a 'dangling' pointer, or an expression that indexes an array
beyond its bounds. Whole categories of bugs that routinely plague C and
C++
programs are thus eliminated." - A. Hejlsberg, The C# Programming
Language

Nov 15 '05 #3

"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Michael A. Covington <lo**@www.covin gtoninnovations .com.for.addres s>
wrote:
See:
http://www.ai.uga.edu/mc/SingleInstance.html

While attempting to use a mutex to allow only one instance of my app to run at a time (Recipe 4.12 in C# Programmer's Cookbook), I found that if the
mutex is in a local variable in Main(), and my program launches any windows before Application.Run (), it will lose the mutex upon doing so. It
shouldn't, as far as I can see. Moving the mutex variable outside Main() and making it static eliminates the problem.

Any ideas? Is there a subtle matter of variable scope and extent that I
haven't understood? Does a process lose its mutexes when it launches a
window? Why?

(The mutex variable still exists, and m.Handle has the same value; but
according to ProcessExplorer , the mutex no longer exists. And all of this happens only for processes launched from Windows, not under the IDE!)


My guess is that the JIT can notice that the Mutex is no longer
referenced, and thus marks it as available for garbage collection. As a
way of testing this, put the line:

GC.KeepAlive (myMutex);

at the *end* of the Main method.

Let me know if that works, and I'll mention it in the FAQ.


I'll try that. Note that inserting additional references to the mutex
variable
(e.g., MessageBox(m.Ha ndle.ToString() ) later on in the Main() method did not
help. If the GC thinks I'm no longer using the mutex variable, it's
mistaken.

In any case I'll investigate. Thanks!
Nov 15 '05 #4
So far, the problem is remarkably hard to reproduce, and I don't want to
post the program in which it actually is observed because it's proprietary
(for a client).

But here's a question.

Should there be any difference between this:

Application.Run (new Form1());

and this?

Form1 f1 = new Form1();
f1.Show();
Application.Run ();

Would the latter keep the garbage collector from realizing that f1's
variables need to persist even when f1 is not visible?
Nov 15 '05 #5
Dear Jon and others,

Adding GC.KeepAlive(mu tex) at the end of the code worked just as well as
making the mutex variable static.

Below is my Main() method, with some names changed to conceal what piece of
software this is. I should add that LaunchFormEdit is not involved in the
cases I'm testing with, and that FormOpeningMenu has a Closing event handler
that calls Application.Exi t.

Further wisdom would be welcome!
Michael

[STAThread]
static void Main(string[] args)
{

// 1. Determine that this is the only instance running

bool createdMutex;
System.Threadin g.Mutex mutex = new
System.Threadin g.Mutex(true,"a sdfasdf",out createdMutex);
// See the GC.KeepAlive below. I don't know why it's necessary.

if (!createdMutex)
{
string msg = "asdfasdfas df is already running.\r\n\r\ n";
System.Windows. Forms.MessageBo x.Show(msg,"asd fasdfasdfasdf") ;
return;
}
// 2. Make a Help Window.
FormHelp formHelp = new FormHelp();
formHelp.Show() ; // Without the GC.KeepAlive, the mutex is released
HERE against my wishes.

// 3. Make an Opening Menu.
theOpeningMenu = new FormOpeningMenu ();
// 4. Start in either the Opening Menu or FormEdit depending on args.
if (args.Length == 0)
theOpeningMenu. Show();
else
LaunchFormEdit( args[0]);

// 5. Let 'er rip! In either of 2 windows as appropriate.
// They both have Closing event handlers to do Application.Exi t() when
the window closes.
Application.Run ();
GC.KeepAlive(mu tex);
}
Nov 15 '05 #6
Jon,

You got it right. It's a matter of the optimizing compiler outsmarting me.

The optimizing compiler is realizing that there are no operations on the
mutex after a certain point (that can't be moved earlier without affecting
the program), so it's disposing of the mutex much earlier than it ought to.

GC.KeepAlive() fixes it, and this is more elegant (and presumably more
reliable) than my solution involving a static global variable.

Thanks! I'm about to revise the full story, which is on
www.ai.uga.edu/mc/SingleInstance.html.
Michael Covington
Associate Director
Artificial Intelligence Center
The University of Georgia
Nov 15 '05 #7
Not sure it has to do with mutex per se. It is more how your hooking up (or
not) to the message loop AFAICT. The following works as expected from the
perspective that the form is displayed and replies to messages and when you
close the form, the Console writes happen. If you remove the "form2" from
the Application.Run () line, the lines after it, do not run. Test it to see
what I mean. To be safe, I would use the standard means of running
Application.Run (new form()) as not sure of side effects of not doing it.

[STAThread]
static void Main()
{
int myVar = 10;
string myString = "Hello";
Form2 form2 = new Form2();
form2.Show();
Application.Run (form2);
Console.WriteLi ne("myVar:"+myV ar);
Console.WriteLi ne("myString:"+ myString);
Console.ReadLin e();
}

--
William Stacey, MVP

"Michael A. Covington" <lo**@www.covin gtoninnovations .com.for.addres s> wrote
in message news:ev******** ******@TK2MSFTN GP12.phx.gbl...
Jon,

You got it right. It's a matter of the optimizing compiler outsmarting me.
The optimizing compiler is realizing that there are no operations on the
mutex after a certain point (that can't be moved earlier without affecting
the program), so it's disposing of the mutex much earlier than it ought to.
GC.KeepAlive() fixes it, and this is more elegant (and presumably more
reliable) than my solution involving a static global variable.

Thanks! I'm about to revise the full story, which is on
www.ai.uga.edu/mc/SingleInstance.html.
Michael Covington
Associate Director
Artificial Intelligence Center
The University of Georgia

Nov 15 '05 #8

"William Stacey [MVP]" <st***********@ mvps.org> wrote in message
news:u1******** ******@tk2msftn gp13.phx.gbl...
Not sure it has to do with mutex per se. It is more how your hooking up (or not) to the message loop AFAICT. The following works as expected from the
perspective that the form is displayed and replies to messages and when you close the form, the Console writes happen. If you remove the "form2" from
the Application.Run () line, the lines after it, do not run. Test it to see what I mean. To be safe, I would use the standard means of running
Application.Run (new form()) as not sure of side effects of not doing it.

[STAThread]
static void Main()
{
int myVar = 10;
string myString = "Hello";
Form2 form2 = new Form2();
form2.Show();
Application.Run (form2);
Console.WriteLi ne("myVar:"+myV ar);
Console.WriteLi ne("myString:"+ myString);
Console.ReadLin e();
}


It turns out that my use of Application.Run () was not the problem.
Application.Run () leaves it up to you to create and show all your windows,
and also make sure that the appropriate one (or more) has a Closing event
handler that ends the application (Application.Ex it()). This I did. See my
other message for the answer to the mutex problem...
Nov 15 '05 #9
The keep alive may get around the issue and glad it works for. However, try
what I showed to reproduce the same thing without the mutex and you don't
need the keep alive. Not hooking up the form inside the Run() does not seem
to be a good thing. And it may have other side effects we don't see at the
moment.

--
William Stacey, MVP

"Michael A. Covington" <lo**@www.covin gtoninnovations .com.for.addres s> wrote
in message news:OI******** ******@TK2MSFTN GP11.phx.gbl...

"William Stacey [MVP]" <st***********@ mvps.org> wrote in message
news:u1******** ******@tk2msftn gp13.phx.gbl...
Not sure it has to do with mutex per se. It is more how your hooking up (or
not) to the message loop AFAICT. The following works as expected from the perspective that the form is displayed and replies to messages and when

you
close the form, the Console writes happen. If you remove the "form2" from the Application.Run () line, the lines after it, do not run. Test it to

see
what I mean. To be safe, I would use the standard means of running
Application.Run (new form()) as not sure of side effects of not doing it.

[STAThread]
static void Main()
{
int myVar = 10;
string myString = "Hello";
Form2 form2 = new Form2();
form2.Show();
Application.Run (form2);
Console.WriteLi ne("myVar:"+myV ar);
Console.WriteLi ne("myString:"+ myString);
Console.ReadLin e();
}


It turns out that my use of Application.Run () was not the problem.
Application.Run () leaves it up to you to create and show all your windows,
and also make sure that the appropriate one (or more) has a Closing event
handler that ends the application (Application.Ex it()). This I did. See

my other message for the answer to the mutex problem...

Nov 15 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
329
by: PL | last post by:
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 {
2
4770
by: Martin Maat | last post by:
Hi. I want to use the same mutex in different classes (web pages in an ASP.NET application). In global.asax.cs, the class that starts up first, I create a Mutex like this: static private Mutex mtxBezoeken = new Mutex(false, "bezoeken"); which compiles and executes just fine. Then in another page I want to write to a file that may also be accessed by global.asax.cs so I want access to
16
3143
by: Ed Sutton | last post by:
I use a mutex to disallow starting a second application instance. This did not work in a release build until I made it static member of my MainForm class. In a debug build, first instance got ownership, second did not and terminated. In a release build, the second instance *also* got ownership. I "fixed" it by making the mutex a static member of my MainForm class. Did the garbage collector eat my mutex because it is not referenced
16
3354
by: mfdatsw1 | last post by:
I need to be certain my application only runs once on a machine, and I implemented a solution using Mutex. The solution was posted many times, but one great link I found is http://www.yoda.arachsys.com/csharp/faq/#one.application.instance The problem is, when I switch users (XP Professional) the second user can open a second instance of the application! How can I prevent this? Here's the relevant part of my code:
1
2053
by: cold80 | last post by:
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
3
4951
by: cold80 | last post by:
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
2
3740
by: cj | last post by:
I take it a mutex is like a synclock but visible outside the program?
8
1393
by: Academia | last post by:
I build the solution. In the bin folder I run the .exe Twice It runs each time. Why doesn't the below code abort the second run?
0
8001
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
7934
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
6742
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
5886
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5445
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
3912
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
3958
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1537
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1270
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.