Recently I am working on a ConsoleApp for job scheduling. This article will not discuss the job scheduling part for now (I will write about it later). This article only discusses how to ensure the operation of a single instance.
ConsoleApp running requirements
1. Start the application when the system starts;
2. Single instance running in each session;
When opening a remote desktop link, only one instance of ConsoleApp is allowed to be started.
3. Only one instance can run within the system;
When multiple remote desktop links are opened, only one instance of ConsoleApp is allowed to be started.
Mutex
Mutex: A synchronization primitive that can also be used for inter-process synchronization.
Visible MSND: http://msdn.microsoft.com/zh-cn/library/system.threading.mutex.aspx
In the introduction of the official document, there is this paragraph
On a server running Terminal Services, a named system mutex can have two levels of visibility. If the name begins with the prefix "Global", the mutex is visible in all terminal server sessions. If the name begins with the prefix "Local", the mutex is only visible in the terminal server session in which it was created. In this case, you can have a separate mutex with the same name in every other terminal server session on the server. If a named mutex is created without specifying a prefix, it will take the prefix "Local". In a terminal server session, two mutexes that differ only in their name prefix are independent mutexes, and these two mutexes are visible to all processes in the terminal server session. That is: the prefix names "Global" and "Local" indicate the scope of the mutex name relative to the terminal server session (not relative to the process).
Unfortunately, no C# example was found. This passage can be understood as:
mutexName= "Local\" +"AppName";
It is only valid for the session in which it was created, which means that when a new remote connection is opened, the ConsoleApp instance will be started again.
mutexName= "Global\" +"AppName";
Valid for all sessions. When multiple remote links are opened, only the first remote link will successfully start the ConsoleApp instance.
Run as a single instance per session
private static void LocalMutex()
{
// Whether to create mutex for the first time
bool newMutexCreated = false;
string mutexName = "Local\" + "tenghoo";
Mutex mutex = null;
try
{
mutex = new Mutex(false, mutexName, out newMutexCreated);
}
catch (Exception ex)
{
Console.Write(ex.Message);
System.Threading.Thread.Sleep(3000);
Environment.Exit(1);
}
// Create mutex for the first time
if (newMutexCreated)
{
Console.WriteLine("Program has started");
//todo: Here is the task to be performed
}
else
{
Console.Write("Another window is already running and will automatically close after 3 seconds...");
System.Threading.Thread.Sleep(1000);
Console.Write("1");
System.Threading.Thread.Sleep(1000);
Console.Write("2");
System.Threading.Thread.Sleep(1000);
Console.Write("3");
Environment.Exit(1);//Exit the program
}
}
System-wide single instance operation
private static void GlobalMutex()
{
// Whether to create mutex for the first time
bool newMutexCreated = false;
string mutexName = "Global\" + "tenghoo";
Mutex mutex = null;
try
{
mutex = new Mutex(false, mutexName, out newMutexCreated);
}
catch (Exception ex)
{
Console.Write(ex.Message);
System.Threading.Thread.Sleep(3000);
Environment.Exit(1);
}
// Create mutex for the first time
if (newMutexCreated)
{
Console.WriteLine("Program has started");
//todo: Here is the task to be performed
}
else
{
Console.Write("Another window is already running and will automatically close after 3 seconds...");
System.Threading.Thread.Sleep(1000);
Console.Write("1");
System.Threading.Thread.Sleep(1000);
Console.Write("2");
System.Threading.Thread.Sleep(1000);
Console.Write("3");
Environment.Exit(1);//Exit the program
}