C'est donc une continuation de ma dernière question - alors la question était donc "Quel est le meilleur moyen de créer un programme en sécurité en termes qu'il doit écrire une double valeur dans un fichier. Si la fonction qui enregistre les valeurs via StreamWriter est appelée par plusieurs threads? Quelle est la meilleure façon de le faire ? "
Et j'ai modifié un code trouvé chez MSDN, que diriez-vous de ce qui suit? Celui-ci écrit correctement tout dans le fichier. P>
4 Réponses :
Le code que vous avez là est subtilement brisé - en particulier, si l'élément de travail en file d'attente fonctionne en premier, il affleurera immédiatement la liste (vide) de la valeur (vide), avant de terminer, après quoi votre travailleur va et remplit la liste. (qui finira par être ignoré). L'événement de réinitialisation automatique ne fait pas non plus rien, car rien ne se soumet ou n'attend jamais son état. P>
Également, puisque chaque thread utilise un verrou différent em>, les verrous n'ont aucune signification! Vous devez vous assurer de détenir une seule serrure partagée chaque fois que vous accédez au Streamwriter. Vous n'avez pas besoin d'un verrou entre le code de rinçage et le code de génération; Il vous suffit de vous assurer que la flush passe après la finition de la génération. P>
Vous êtes probablement sur la bonne voie, cependant, bien que j'utilise un tableau de taille fixe au lieu d'une liste et affleurez toutes les entrées de la matrice lorsqu'elle est complète. Cela évite la possibilité de manquer de mémoire si le fil est de longue durée. P>
Comment se fait-il que le rinçage se produira si la liste est vide?
J'ai expliqué cela dans ma réponse - l'élément de travail en file d'attente WorkMethod code> peut exécuter avant i> le fil
threadmethod code>. Et cela peut également fonctionner après. Vous ne pouvez pas prédire lequel, parce que vous n'avez défini aucune sorte de commande explicite ici.
Vous pouvez également utiliser Réinventer ces roues correctement est étonnamment difficile. Je recommande vivement d'utiliser les classes conçues pour ce type de besoin ( thread code> et
weeuueropeworkitem code> sont les API les plus bas disponibles pour le filetage em>. Je ne les utiliserais pas à moins d'absolument, finalement, n'avait pas d'autre choix. Essayez la classe code> de la classe code> pour une abstraction de niveau beaucoup plus élevé. Pour plus de détails, Voir mon article de blog récent sur le sujet a >. P>
blockingcollection
Task Code> et
BlockingCollection code>, pour être spécifique). Ils sont intégrés à la structure .NET 4.0 et sont disponibles comme un complément pour .NET 3.5 . P>
La «bonne réponse» dépend vraiment de ce que vous recherchez en termes de comportement de verrouillage / blocage. Par exemple, la chose la plus simple serait de sauter la structure de données intermédiaire, il suffit de disposer d'une méthode ErreurSvalues de manière à ce que chaque thread "signalant" ses résultats soit avancé et les écrit au fichier. Quelque chose comme: p> Bien sûr, cela signifie que les threads de travailleurs se serifisent pendant leurs phases "Résultats de rapport" - en fonction des caractéristiques de performance, cela peut être tout simplement bien (5 minutes à Générez, 500ms à écrire, par exemple). P>
Vous dites donc que vous voulez que vous souhaitiez un tas de threads d'écrire des données sur un seul fichier à l'aide d'un streamwriter? Facile. Il suffit de verrouiller l'objet StreamWriter.
Le code ici créera 5 threads. Chaque thread effectuera 5 "actions" et à la fin de chaque action, il écrira 5 lignes sur un fichier nommé "fichier". P> Le résultat doit être un fichier. "Fichier" avec 125 lignes dedans avec toutes les "actions" effectuées simultanément et le résultat de chaque action écrite de manière synchrone au fichier. p> p>
Vous ne devriez pas vous bloquer des objets dans lesquels vous ne contrôlez pas leur implémentation comme celle-ci - que si elle se verrouille en interne dans un autre fil? - Vous devez créer un nouvel objet code> à utiliser comme verrouillage.
N'utilisez pas un objet séparé pour un verrou. Verrouiller un objet directement est le seul moyen de s'assurer que tous les threads pouvant voir qu'un objet peuvent obtenir une serrure exclusive sur l'objet.
@Lunatisxperimentalist: Le verrouillage d'un objet directement ne garantit pas que toutes les threads obtiennent une serrure exclusive. Si un développeur oublie de verrouiller l'objet dans un endroit particulier, il a un accès incontrôlé, quel que soit votre objet tous les autres threads utilisent pour le verrouillage.