Partage de données entre AppDomains
J'ai un processus qui peut avoir plusieurs domaines d'application. Chaque domaine d'application de collecter des statistiques. Au bout d'un certain temps, j'ai envie d'accumuler ces statistiques et les enregistrer dans un fichier.
Une façon de faire cela est de l'accès distant, qui je veux éviter.
La seule autre technique que j'ai à l'esprit est de sauver chaque domaine d'application données dans un fichier, et après un certain temps, l'un des domaine d'application collecte toutes les données et de les accumuler.
Mais l'idéal serait, si tout cela pouvait être fait en mémoire, sans le coût de la sérialisation de l'information entre les domaines d'application. Quelqu'un a des idées?
source d'informationauteur ata
Vous devez vous connecter pour publier un commentaire.
Le seul moyen d'éviter la sérialisation est de représenter vos données à l'aide d'objets qui dérivent de MarshalByRefObject, mais dans ce cas, vous aurez tout de même le coût de la formation des trains à travers le domaine d'application limites. Cela peut également impliquer le refactoring/ré-écriture d'une grande partie de votre code.
En supposant triage par référence n'est pas une option, vous devrez serialise à un certain point. Il ne peut tout simplement pas être évitée. Une façon de le faire c'est que Neil Barnwell suggère, avec une base de données, l'autre avec un fichier local comme vous le suggérez vous-même.
Une autre façon qui peut ou peut ne pas possible, en fonction de votre délai de livraison et/ou de l' .NET 4.0 adoption, serait d'utiliser un fichier mappé en mémoire, voir .Net Framework 4.0: en Utilisant les fichiers mappés en mémoire.
Il est possible de partager des données entre des domaines d'application sans les frais de Triage. Mais c'est plutôt une hacky. Vous pouvez créer une source de données de l'objet, qui est partagée par référence entre tous les domaines d'application. De cette façon, vous obtenez toutes les données dans un objet partagé sans les frais de Triage. Semble trop facile pour être vrai?
La première chose est de savoir comment partager des données entre des domaines d'application sans la Sérialisation. Pour cela, vous obtenez l'adresse d'objet de votre source de données de l'objet via le Maréchal.UnsafeAddrOfPinnedArrayElement. Ensuite, vous passez cette IntPtr à tous les domaines d'application qui sont intéressés par cela. Dans le domaine d'application cible, vous devez lancer cette IntPtr retour à un objet de référence qui peut être fait JIT::CastAny qui est fait si vous retournez un objet à partir d'une méthode et de pousser le pointeur sur la pile.
Alto vous avez partagé un objet comme un simple pointeur entre les domaines d'application et vous obtenez InvalidCastExceptions. Le problème est que vous devez définir pour l'ensemble de vos domaines d'application LoaderOptimization.Multidomaine pour s'assurer que l'assemblée qui définit l'partagée type de données est chargé dans le domaine d'application de type neutre qui a la même Méthode, le pointeur de la Table entre tous les domaines d'application.
Vous pouvez trouver un exemple d'application qui fait exactement ce que la partie de WMemoryProfiler. Voir ce lien pour plus de explication détaillée et lien de téléchargement à l'exemple de code.
Le code de base est
J'ai tendance à dire juste utiliser l'accès distant. D'écrire les données dans un fichier nécessite la sérialisation, trop. La sérialisation semble presque inévitable de ce que jamais la technologie que vous utilisez. Vous devez transférer des données à partir d'un domaine d'application à l'autre à l'aide de certains canaux et vous aurez pour sérialiser les données afin d'obtenir à travers le canal.
Le seul moyen d'éviter la sérialisation semble être l'utilisation de la mémoire partagée, de sorte que les deux domaines d'application peuvent accéder aux données sans jamais avoir à passer par l'intermédiaire d'un canal. Même au fond de clonage des données à partir d'un domaine d'application de la mémoire dans l'autre mémoire est, à sa base, rien de plus qu'une sérialisation binaire (où le résultat n'est pas nécessairement stockées dans consécutives emplacements de mémoire).
Je ne l'apprécie que vous voulez garder cela en mémoire, mais ma première suggestion serait d'écrire les données dans une base de données et de requêtes à partir de là. L'accès distant est toujours un appel à distance, qui est l'endroit où beaucoup de "coût" de l'aide d'un serveur de base de données vient de, et vous auriez à construire dans l'opération de manutention pour vous assurer de ne pas perdre de données. Si vous écrivez à une base de données SQL Server que vous avez l'appui de transaction prêt et en attente pour vous, et c'est vite-vite-vite pour les requêtes.