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 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
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
"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!
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?
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);
}
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
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
"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...
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...
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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
{
|
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
|
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
|
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:
|
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
| |
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
|
by: cj |
last post by:
I take it a mutex is like a synclock but visible outside the program?
|
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?
|
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...
|
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,...
|
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...
| |
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...
|
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();...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
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...
| |