J'ai un système qui crée des Parfois, plusieurs threads accèdent au système: p>
Évidemment, le lecteur commence parfois à lire avant que l'écrivain ait terminé l'écriture, ce qui cause une exception à lancer dans le lecteur: P>
system.xml.xmexception: l'élément racine est manquant. P>
blockQuote>
Ce n'est pas particulièrement surprenant, mais y a-t-il un moyen de faire ce système-sécurité? P>
L'une des approches ci-dessus serait, je crois, résoudre mon problème. Il n'est pas nécessaire que l'écriture et la lecture se produisent simultanément. En fait, je serais parfaitement heureux si je pouvais simplement dire au client demander le J'ai le contrôle total sur le code qui crée le Y a-t-il un moyen de faire ce système de sécurité? p> xmlreader code> et xmlwriter code> les cas et les transmet aux clients forts>, afin que les clients puissent écrire et lire Xml. P>
xmlwriter code> instance et commence à écrire li>
xmlreader code> instance représentant le même document XML et commence la lecture. li>
ol>
MemoryReam code> en tant que magasin de données sous-jacent, mais cela ne semblait pas fonctionner. Li>
xmlreader code> que le lecteur n'est pas encore prêt, et il doit réessayer plus tard. Cependant, cela nécessite qu'il y ait un moyen de détecter que l'auteur écrit toujours. P>
xmlreader code> et xmlwriter code>, mais je ne peux pas changer l'API publique. Je peux utiliser un chaîne code>, un stringbuilder code>, un MemoryStream code> ou tout autre objet en mémoire qui obtiendra le travail effectué, comme le stockage sous-jacent et je peux utiliser toute classe dérivée de xmlreader code> et xmwriter code>. p>
6 Réponses :
Votre meilleur pari est probablement de créer des classes personnalisées qui dérivent de Vous pouvez alors simplement faire les méthodes dans le bloc de lecteur jusqu'à ce que l'écriture ne soit pas en cours. P> xmlreader code> et xmwriter code>. Vous pouvez leur ajouter un objet de synchronisation commune et utiliser quelque chose comme un readwriterlockslim code> pour coordonner la lecture et l'écriture. Vous devriez déterminer dans la classe d'écrivain ce que vous voulez dire lorsque vous dites que c'est «fait» (disposé »(DONE? Fait écrit un noeud unique, même si ce n'est pas complètement fait? Etc.) P>
Merci, cette solution était tout ce dont j'avais besoin. En fait, je pourrais obtenir uniquement la création d'une classe dérivée de xmlwriter code>, qui comprenait un rappel lors de son élimination. Jusqu'à ce que le rappel survient, je dis simplement aux lecteurs que le document n'est pas encore prêt, puis lorsque le rappel est disponible, le document devient disponible.
Une idée simple est de créer un dictionnaire (éventuellement statique) de documents en cours d'écriture. Bien que ce document soit dans ce document, les demandes de lecture du dictionnaire sont bloquées ou rejetées. P>
Bonne idée Il est de créer une copie de fichier XML dans un verrou qui affectait également sur un xmlwriter.
code de l'écrivain: p> code de lecteur: p>
Pourquoi copier si vous verrouillez le fichier?
On dirait que vous avez besoin de quelque chose de similaire à la pipedrader / pipedWriter en Java. http://docs.oracle.com/javase/ 7 / DOCS / API / JAVA / IO / PIPEDREADER.HTML . On dirait que .NET n'a rien de tel: Les équivalents de Java de PipeDreader / VoipedWriter en C # ? . p>
Vous pouvez faire la même chose que dans Java en implémentant votre propre système.IO.TextWriter et System.IO.TexTreader à l'aide de ce code Java comme base: P>
Cela ressemble à la solution générale correcte à ce type de problème (SO +1). J'espérais que cela a déjà été construit dans la BCL et que j'avais juste négligé quelque chose d'évident, mais cela semble ne pas être le cas. Cependant, comme cette solution suggérée est plutôt complexe et que je pouvais gérer avec une solution plus simple, j'ai sélectionné une autre réponse comme «la» réponse. Merci.
Qu'est-ce que vous recherchez est un flux qui permet à un fil d'écrire tandis que l'autre lit. Le .NET Framework ne fournit pas une telle chose. Vous pouvez potentiellement le faire avec un tuyau nommé, mais j'ai trouvé ce lourd. J'ai donc écrit ce que j'ai appelé un pour l'utiliser avec le Le thread de producteur créerait un Le thread de lecteur est similaire: p> Assurez-vous que dans vos paramètres de l'écrivain, vous définissez La clé ici est que comprendre, il s'agit d'une structure en mémoire. Si vous souhaitez persister le XML aussi, vous devrez le faire d'une autre manière. Bien que je suppose que vous pouvez dériver de producteur producteur code>. C'est juste une file d'attente circulaire enveloppée dans une interface code> code>. Voir Construire un nouveau type de flux pour une description et une source complète . xmlwriter code> et xmlreader code>, vous feriez quelque chose comme ceci: p> xmlwriter code> qui écrit au flux: p> fermerOutput = false code>, et dans le jeu de paramètres de lecteur fermerInput = false code>. Sinon, le flux pourrait être éliminé prématurément. P> producteur producteur.fread code> bloque jusqu'à ce qu'il puisse lire des données. Sauf si la fin du flux n'a été signalée en appelant en terminaison code>. P> producteur producteur code> et remplacer la méthode code> code> de sorte que cela sortit sur le fichier ainsi que la copie des choses sur le tampon interne. P> P >
Cela ressemble à la solution générale correcte à ce type de problème (SO +1). J'espérais que cela a déjà été construit dans la BCL et que j'avais juste négligé quelque chose d'évident, mais cela semble ne pas être le cas. Cependant, comme cette solution suggérée est plutôt complexe et que je pouvais gérer avec une solution plus simple, j'ai sélectionné une autre réponse comme «la» réponse. Merci.
est-il possible de rendre le lecteur attendre jusqu'à ce que em> l'auteur ait terminé l'écriture? P>
Oui avec un Construction de la synchronisation de fil hybride , par ex. ManualReseteventsLIM , comme suit: P> XXX PRE>
Sortie de la console: P>
private static void CreateXmlDocument(XmlWriter writer) { writer.WriteStartDocument(); writer.WriteStartElement("Product"); writer.WriteAttributeString("ID", "001"); writer.WriteAttributeString("Name", "Soap"); writer.WriteElementString("Price", "10.00"); writer.WriteStartElement("OtherDetails"); writer.WriteElementString("BrandName", "X Soap"); writer.WriteElementString("Manufacturer", "X Company"); writer.WriteEndElement(); writer.WriteEndDocument(); }
Cette solution s'appuie sur la synchronisation chez le client. Cependant, je cherche une solution qui ne nécessite pas que les clients soient synchronisés, car l'écrivain et le lecteur ne peuvent avoir aucune connaissance de l'autre.
Oh, je vois ... J'ai mis l'accent sur le fait que vous avez le contrôle total sur le code qui crée le xmlreader code> et xmwriter code> instances.
Vous devez créer un mécanisme de commande / checkin.
Vous pouvez probablement créer votre propre flux qui servirait de fournisseur à votre lecteur / écrivain XML, et il bloquera une opacité de lecture jusqu'à ce qu'il sait que toutes les écrivies sont terminées. Une fois que l'écriture est survenue, débloquer lire et procéder heureusement. Vous pouvez probablement toujours utiliser Morthstream comme support sur votre flux personnalisé.
Lorsque vous dites "clients" parlez-vous plusieurs processus? (s'il vous plaît dites-moi non).
@PeterRitchie Non, juste d'autres objets dans le même processus (mais sur différents threads).
@ LB2: Le blocage du niveau du flux peut être insuffisant, car le flux n'a aucune idée du moment où une opération est réellement complète.
Ouf, un RWL sonne exactement ce dont vous avez besoin.
@Adamrobinson basé sur "est-il possible de faire attendre le lecteur jusqu'à ce que l'écrivain ait terminé l'écriture?" I> Il semble que le contenu est petit, alors on peut attendre que
XMLWriter code> est fermé et la détecter par elle fermant le flux sous-jacent, ce qui servirait de signal pour débloquer le flux de lecture. Mais je suis d'accord avec un commentaire plus tard que RWL est probablement ce que OP est vraiment recherché.