7
votes

C #: Comment empêcher deux instances d'une application de faire la même chose en même temps?

Si vous avez deux threads dans une application et que vous ne voulez pas qu'ils exécutent une certaine pièce de code simultanément, vous pouvez simplement mettre un verrou sur la pièce de code, comme celui-ci:

lock (someObject) {
    // ... some code
}


4 commentaires

Vous utilisez .NET et placez-vous sur mutex étant spécifique à Windows?


@Anon: mono-project.com/main_page


@Randolpho: L'objectif de l'OMS est de mettre en œuvre toute la bibliothèque .NET. Y compris system.threading.mutex . Si cela fait partie de la bibliothèque .NET, vous pouvez vous attendre à ce qu'il fonctionne sur n'importe quelle plate-forme .NET (y compris mono, une fois qu'elle finit la mise en œuvre de cette partie de celui-ci).


Oh, je sais. J'étais juste dire


6 Réponses :


4
votes

J'ai utilisé avec succès Mutex pour exactement cet objectif et peut confirmer que cela fonctionne, bien qu'il y ait eu quelques bizarreries.

J'ai un exemple de code de travail complet à la maison. Il suffit de poster un commentaire à cette réponse si vous souhaitez que je ajoute l'exemple de code ce soir.

mise à jour:

Voici le code down de mon app. Ceci est une application de console, mais le même principe devrait s'appliquer à tout type d'application. Exécuter avec un argument de ligne de commande de xxx

pour tester la logique mutex.

Notez que dans mon cas, le mutex gère vraiment la plupart du processus, mais Il n'y a aucune raison pour laquelle vous devez l'utiliser de cette façon. C'est juste ce qui était nécessaire dans ce cas. xxx


2 commentaires

@Timwi: Je posterai le code ce soir. J'ai un peu gratté ma tête pour que cela fonctionne, mais maintenant, il est utilisé dans une application de production à volume élevé sans aucun problème.


Le finalement pourrait s'écraser si. Si le mutex est null, alors étroite ne fonctionnerait pas. Je ne sais pas comment cela pourrait être nul, mais s'il ne peut pas que le test de NULL ne soit pas nécessaire.



4
votes

4 commentaires

Oui, un mutex nommé est la façon dont les processus peuvent partager cette primitive Windows.


J'ai fait. Cela n'a pas fonctionné. Un code d'exemple de travail serait bien.


@Timwi - Pourriez-vous fournir le code que vous utilisez qui ne fonctionne pas? Il peut y avoir quelque chose d'autre que vous faites, ce qui cause cela échoue.


Je soupçonne que @timwi essaie d'essayer de prendre le mutex plusieurs fois, mais ne le libérant qu'une seule fois.



0
votes

Bien que je vous recommande d'utiliser Mutex et de rechercher si le problème est ou non votre code lui-même, une alternative très complexe très fragile peut être d'utiliser des "fichiers de verrouillage".

Fondamentalement, vous créez un fichier temporaire dans le système de fichiers avec un nom que les deux processus reconnaissent. Si le fichier existe, la serrure est en place; L'autre processus devrait libérer d'autres serrures, attendre et tenter de ré-acquérir. Si le fichier n'existe pas, le verrou n'est pas en place; Le processus doit créer le fichier pour compléter le traitement et poursuivre le traitement, supprimer le fichier lors du relâchement de la serrure.

Comme je l'ai dit, c'est très complexe et fragile, mais cela n'utilise pas MuTex.

Alternativement, utilisez MuTex.


0 commentaires

0
votes

Si vous ne voulez pas utiliser un mutex, je dirais que vous voulez rouler votre propre utilisation d'un fichier qui existe une solution simple. Si le fichier existe, je ne commence pas un nouveau. Cependant, vous devrez gérer les cas d'exception dans lesquels un processus se termine tôt et que le fichier n'est pas nettoyé.

retourner au mutex pendant un moment, il s'agit simplement d'un «objet» du système d'exploitation pour le besoin d'un meilleur terme. Vous en avez vraiment besoin comme ceci sur chaque système d'exploitation que vous utilisez. Je suis sûr que l'autre .net CLR vous permettra également d'accéder à ces primitives du système. Je voudrais juste terminer chacun à l'aide d'un assemblage défini qui pourrait être différent sur chaque plate-forme.

J'espère que cela a du sens.


0 commentaires

5
votes

J'ai deux applications:

ConsoleApplication1.cs xxx

consoleapplication2.cs xxx

Démarrer ConsoleApplication1, Suivi de ConsoleAllication2 fonctionne parfaitement sans erreurs. Si votre code est toujours en bombe, c'est un bogue avec votre code, pas la classe mutex.


1 commentaires

Merci beaucoup. J'aurais pu juré que c'est exactement ce que j'ai fait, mais j'ai dû faire quelque chose différemment parce que cela n'a pas fonctionné et que cela ne le fait pas. Merci encore.



-1
votes

Peut-être que je simplifie le problème, mais je viens de vérifier le nom du processus dans le passé.

Vous pouvez simplement utiliser cette fonction pour attendre que l'autre soit effectuée, puis exécutez le processus actuel. xxx


1 commentaires

Votre réponse nécessite que j'attends le processus entier à finir, ce qui ne fait pas pertinenter ma question.