2010-09-03 10 views
13

J'ai écrit une API qui sera utilisée dans la même boîte dans (1) un service Windows, (2) une application Web et (3) une application Windows Forms. Ils ont tous besoin de partager un très petit ensemble de données communes (quelques ints, une date et une chaîne que je pourrais mettre en tant que propriétés d'une seule classe).Verrouillage inter-processus en C#

Quel type de mécanisme de verrouillage puis-je utiliser un processus croisé pour que les trois processus puissent partager les ressources en toute sécurité et ne pas se heurter à des conflits?

Aucune base de données s'il vous plaît, à la recherche d'une solution qui ne nécessite pas de dépendances supplémentaires. De préférence, la solution utiliserait la mémoire partagée ou le système de fichiers d'une manière ou d'une autre.

+0

Le titre de votre question suggère qu'il s'agit d'un "verrouillage", mais la véritable question semble porter uniquement sur les données. Précisez s'il vous plaît. –

+1

Vous l'avez dit! – Wells

Répondre

17

Pour le verrouillage inter-processus en C#/.Net, vous pouvez utiliser un named system Mutex.

+0

J'ai utilisé Mutex pour cela. Mais un seul processus obtient le verrou. D'autres sont incapables d'atteindre ce verrou. J'ai posté une question http://stackoverflow.com/questions/41359056/how-can-i-distribute-the-mutex-lock-between-processes/41359378#41359378 – TBAG

+1

@TBAG Je vois que vous êtes spamming Stackoverflow avec beaucoup des questions (et des commentaires sur des questions sans rapport) à propos de ce «problème» que vous vivez. Un mutex est utilisé pour garantir un accès exclusif à une ressource partagée entre les processus. Ce n'est pas pour la planification du travail ou l'accès à travers plusieurs threads. Votre compréhension du fonctionnement du mutex - "Si trois méthodes appellent ce constructeur, toutes devraient appeler de manière séquentielle ou à la ronde." - n'est pas correct et c'est pourquoi vous n'obtenez pas le comportement que vous attendez. –

2

Utilisez un objet EventWaitHandle pour créer un événement nommé que chaque processus peut verrouiller ou bloquer. Fonctionne dans .NET 2.0 et versions ultérieures.

1

En fonction de votre question, cela ressemble à ce dont vous avez besoin. Ainsi, l'un des processus héberge les données partagées et les autres processus doivent accéder à ces données. Si ce qui précède est correct, vous pouvez utiliser un verrouillage de processus simple comme un moniteur pour protéger les données partagées et exposer un point de terminaison WCF pour fournir un accès aux données d'un autre processus. L'utilisation d'un transport de tuyau nommé pour la communication WCf, sera très efficace pour la communication entre les processus sur la même boîte. Il n'y aurait pas besoin de verrouillage de processus croisé, sauf si vous utilisiez une ressource partagée comme un fichier mappé en mémoire pour partager les données, mais pour être honnête, cela serait fastidieux et nécessiterait de gérer manuellement beaucoup de choses que WCF prendrait attention à l'avantage que vous pourriez éventuellement mettre à l'échelle de la boîte unique à plusieurs boîtes si jamais vous deviez.

1

Si toutes vos applications résident sur une même machine, vous pouvez utiliser des primitives de synchronisation interprocess comme les mutex nommés et la mémoire partagée. Mais je pense que la meilleure approche serait d'utiliser quelque chose comme les services WCF (qui pourraient résider dans le service Windows) et d'exposer toutes les informations nécessaires par contrat spécifié. Dans ce cas, toute cette application pourrait résider sur des machines différentes, mais de toute façon cette solution plus propre et robuste.

+0

plus un pour l'aveuglement. Mutexes peut être une solution "solution miracle" mais jamais infaillible. :) –

1

Vous pouvez utiliser MSMQ pour fournir des files d'attente partagées entre vos applications, l'une des applications jouant le rôle de maître; le service Windows serait le meilleur choix s'il est toujours en cours d'exécution.

J'utilise System.Data.Sqlite pour communiquer entre les services Windows et les applications. Même si vous n'avez pas indiqué de base de données, vous pourriez trouver cela un compromis valable. C'est une base de données intégrée sans charge administrative. Vous "expédiez" en incluant une seule DLL dans vos applications, et il enregistre vos données dans un seul fichier. Pensez-y comme un fichier persistant auquel vous accédez en utilisant des instructions SQL via ADO.Net; il arbore même une interface LINQ. Vous obtenez le verrouillage par le biais de transactions standard (avec rollback) et offre également un cryptage. Vous pouvez modifier et afficher son contenu à l'aide de l'Explorateur de services Visual Studio. Il fonctionne sur .Net 3.5 et .Net 4. Et c'est open-source sans aucune restriction. Vous pouvez ajouter des colonnes et des tableaux sans casser les fonctionnalités existantes. Comme le déploiement est aussi simple que l'ajout d'une DLL à votre solution, il est beaucoup plus facile à déployer et à prendre en charge. Et puisque la chaîne de connexion pointe vers un fichier, il est facile de l'atteindre à partir de machines distantes. Peut-être pas aussi élégant que les files d'attente partagées ou mutexes, mais ses choses grandement simplifiées pour moi.

+0

"Même si vous avez dit aucune base de données, vous pourriez trouver cela un compromis digne." Douteux, considérant qu'il s'agit à la fois d'une base de données et d'une dépendance supplémentaire; tous les deux, il a explicitement rejeté comme des solutions. – Dan