Récemment, je travaille sur une ConsoleApp pour la planification des tâches pour l'instant (j'en parlerai plus tard). Cet article explique uniquement comment assurer le fonctionnement d'une seule instance.
Exigences d'exécution de ConsoleApp
1. Démarrez l'application au démarrage du système ;
2. Instance unique exécutée dans chaque session ;
Lors de l’ouverture d’un lien de bureau distant, une seule instance de ConsoleApp peut être démarrée.
3. Une seule instance peut s'exécuter dans le système ;
Lorsque plusieurs liens de bureau distant sont ouverts, une seule instance de ConsoleApp peut être démarrée.
Mutex
Mutex : Une primitive de synchronisation qui peut également être utilisée pour la synchronisation inter-processus.
MSND visible : http://msdn.microsoft.com/zh-cn/library/system.threading.mutex.aspx
Dans l'introduction du document officiel, il y a ce paragraphe
Sur un serveur exécutant les services Terminal Server, un mutex système nommé peut avoir deux niveaux de visibilité. Si le nom commence par le préfixe « Global », le mutex est visible dans toutes les sessions du serveur Terminal Server. Si le nom commence par le préfixe « Local », le mutex n'est visible que dans la session du serveur Terminal Server dans laquelle il a été créé. Dans ce cas, vous pouvez avoir un mutex distinct portant le même nom dans toutes les autres sessions de serveur de terminal sur le serveur. Si un mutex nommé est créé sans spécifier de préfixe, il prendra le préfixe "Local". Dans une session de serveur de terminal, deux mutex qui diffèrent uniquement par leur préfixe de nom sont des mutex indépendants, et ces deux mutex sont visibles par tous les processus de la session de serveur de terminal. Autrement dit : les noms de préfixe « Global » et « Local » indiquent la portée du nom du mutex par rapport à la session du serveur Terminal Server (et non par rapport au processus).
Malheureusement, aucun exemple C# n'a été trouvé. Ce passage peut être compris comme :
mutexName= "Local\" +"AppName";
Il n'est valable que pour la session dans laquelle il a été créé, ce qui signifie que lorsqu'une nouvelle connexion à distance est ouverte, l'instance ConsoleApp sera redémarrée.
mutexName= "Global\" +"AppName";
Valable pour toutes les sessions Lorsque plusieurs liens distants sont ouverts, seul le premier lien distant démarrera avec succès l’instance ConsoleApp.
Exécuter en tant qu'instance unique par session
vide statique privé LocalMutex()
{
// S'il faut créer un mutex pour la première fois
bool newMutexCreated = false;
chaîne mutexName = "Local\" + "tenghoo" ;
Mutex mutex = nul ;
essayer
{
mutex = new Mutex(false, mutexName, out newMutexCreated);
}
attraper (Exception ex)
{
Console.Write(ex.Message);
Système.Threading.Thread.Sleep(3000);
Environnement.Exit(1);
}
// Crée un mutex pour la première fois
si (nouveauMutexCréé)
{
Console.WriteLine("Le programme a démarré");
//todo : Voici la tâche à effectuer
}
autre
{
Console.Write("Une autre fenêtre est déjà en cours d'exécution et se fermera automatiquement après 3 secondes...");
Système.Threading.Thread.Sleep(1000);
Console.Write("1");
Système.Threading.Thread.Sleep(1000);
Console.Write("2");
Système.Threading.Thread.Sleep(1000);
Console.Write("3");
Environment.Exit(1);//Quitter le programme
}
}
Opération d'instance unique à l'échelle du système
vide statique privé GlobalMutex()
{
// S'il faut créer un mutex pour la première fois
bool newMutexCreated = false;
chaîne mutexName = "Global\" + "tenghoo" ;
Mutex mutex = nul ;
essayer
{
mutex = new Mutex(false, mutexName, out newMutexCreated);
}
attraper (Exception ex)
{
Console.Write(ex.Message);
Système.Threading.Thread.Sleep(3000);
Environnement.Exit(1);
}
// Crée un mutex pour la première fois
si (nouveauMutexCréé)
{
Console.WriteLine("Le programme a démarré");
//todo : Voici la tâche à effectuer
}
autre
{
Console.Write("Une autre fenêtre est déjà en cours d'exécution et se fermera automatiquement après 3 secondes...");
Système.Threading.Thread.Sleep(1000);
Console.Write("1");
Système.Threading.Thread.Sleep(1000);
Console.Write("2");
Système.Threading.Thread.Sleep(1000);
Console.Write("3");
Environment.Exit(1);//Quitter le programme
}