Kürzlich arbeite ich an einer ConsoleApp für die Jobplanung. In diesem Artikel wird der Jobplanungsteil vorerst nicht behandelt (ich werde später darüber schreiben). In diesem Artikel wird nur erläutert, wie der Betrieb einer einzelnen Instanz sichergestellt wird.
Anforderungen für die Ausführung der ConsoleApp
1. Starten Sie die Anwendung, wenn das System startet.
2. Einzelne Instanz, die in jeder Sitzung ausgeführt wird;
Beim Öffnen eines Remote-Desktop-Links darf nur eine Instanz von ConsoleApp gestartet werden.
3. Innerhalb des Systems kann nur eine Instanz ausgeführt werden.
Wenn mehrere Remote-Desktop-Links geöffnet sind, darf nur eine Instanz von ConsoleApp gestartet werden.
Mutex
Mutex: Ein Synchronisationsprimitiv, das auch für die Synchronisation zwischen Prozessen verwendet werden kann.
Sichtbares MSND: http://msdn.microsoft.com/zh-cn/library/system.threading.mutex.aspx
In der Einleitung des offiziellen Dokuments gibt es diesen Absatz
Auf einem Server, auf dem Terminaldienste ausgeführt werden, kann ein benannter Systemmutex zwei Sichtbarkeitsebenen haben. Wenn der Name mit dem Präfix „Global“ beginnt, ist der Mutex in allen Terminalserversitzungen sichtbar. Wenn der Name mit dem Präfix „Local“ beginnt, ist der Mutex nur in der Terminalserversitzung sichtbar, in der er erstellt wurde. In diesem Fall können Sie in jeder anderen Terminalserversitzung auf dem Server einen separaten Mutex mit demselben Namen haben. Wenn ein benannter Mutex ohne Angabe eines Präfixes erstellt wird, erhält er das Präfix „Local“. In einer Terminalserversitzung sind zwei Mutexe, die sich nur in ihrem Namenspräfix unterscheiden, unabhängige Mutexe, und diese beiden Mutexe sind für alle Prozesse in der Terminalserversitzung sichtbar. Das heißt: Die Präfixnamen „Global“ und „Local“ geben den Geltungsbereich des Mutex-Namens relativ zur Terminalserversitzung an (nicht relativ zum Prozess).
Leider wurde kein C#-Beispiel gefunden. Diese Passage kann wie folgt verstanden werden.
mutexName= "Local\" +"AppName";
Sie ist nur für die Sitzung gültig, in der sie erstellt wurde. Das bedeutet, dass beim Öffnen einer neuen Remote-Verbindung die ConsoleApp-Instanz erneut gestartet wird.
mutexName= "Global\" +"AppName";
Gültig für alle Sitzungen. Wenn mehrere Remote-Links geöffnet sind, startet nur der erste Remote-Link die ConsoleApp-Instanz erfolgreich.
Als einzelne Instanz pro Sitzung ausführen
private static void LocalMutex()
{
// Ob Mutex zum ersten Mal erstellt werden soll
bool newMutexCreated = false;
string mutexName = "Local\" + "tenghoo";
Mutex mutex = null;
versuchen
{
mutex = new Mutex(false, mutexName, out newMutexCreated);
}
Catch (Ausnahme ex)
{
Console.Write(ex.Message);
System.Threading.Thread.Sleep(3000);
Environment.Exit(1);
}
// Mutex zum ersten Mal erstellen
if (newMutexCreated)
{
Console.WriteLine("Programm wurde gestartet");
//todo: Hier ist die auszuführende Aufgabe
}
anders
{
Console.Write("Ein anderes Fenster läuft bereits und wird nach 3 Sekunden automatisch geschlossen...");
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);//Programm verlassen
}
}
Systemweiter Einzelinstanzbetrieb
private static void GlobalMutex()
{
// Ob Mutex zum ersten Mal erstellt werden soll
bool newMutexCreated = false;
string mutexName = "Global\" + "tenghoo";
Mutex mutex = null;
versuchen
{
mutex = new Mutex(false, mutexName, out newMutexCreated);
}
Catch (Ausnahme ex)
{
Console.Write(ex.Message);
System.Threading.Thread.Sleep(3000);
Environment.Exit(1);
}
// Mutex zum ersten Mal erstellen
if (newMutexCreated)
{
Console.WriteLine("Programm wurde gestartet");
//todo: Hier ist die auszuführende Aufgabe
}
anders
{
Console.Write("Ein anderes Fenster läuft bereits und wird nach 3 Sekunden automatisch geschlossen...");
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);//Programm verlassen
}