En parallèle.ForEach questions en Lecture et en Écriture Sur Un Fichier, le Fichier Est En cours d'Utilisation d'Erreur
Je suis vraiment confus au sujet de Parallèle.ForEach... Comment ça fonctionne?
Le code ci-dessous a une erreur -> File Is In Use
Parallel.ForEach(list_lines_acc, (line_acc, list_lines_acc_state) =>
{
FileStream file =
new FileStream(GPLfilePath, FileMode.Open, FileAccess.ReadWrite);
StreamReader reader = new StreamReader(file);
var processed = string.Empty;
Ok_ip_port = string.Empty;
while (reader.EndOfStream)
{
if (string.IsNullOrEmpty(Ok_ip_port))
{
Ok_ip_port = reader.ReadLine();
}
else
{
string currentLine = reader.ReadLine();
processed += currentLine + Environment.NewLine;
}
}
StreamWriter writer = new StreamWriter(file);
writer.Write(processed);
reader.Close();
writer.Close();
file.Close();
});
Vous s'il vous plaît me montrer comment puis-je résoudre ce problème? Ce code est juste un exemple.
Je veux travailler avec les tableaux de chaîne & les Listes Parallèles.ForEach, mais il y a toujours un problème pour l'ajout ou la modification de ces collections. Pouvez-vous nous donner un exemple? Je suis à l'aide de Visual Studio 2010 + .NET Framework 4.0
peut-être parce que de votre FileAccess mode.Êtes-vous essayer de modifier le fichier que vous avez ouvert pour la lecture.
une double question: stackoverflow.com/questions/9913251/...
Vous voulez plusieurs threads à écrire dans le même fichier?
avec un numéro de série car il n'y a pas d'erreur sur ce que les codes. alors que le problème est parallèle pour...
Vous code n'a aucun sens. Pourquoi à l'aide de l'aide de
une double question: stackoverflow.com/questions/9913251/...
Vous voulez plusieurs threads à écrire dans le même fichier?
avec un numéro de série car il n'y a pas d'erreur sur ce que les codes. alors que le problème est parallèle pour...
Vous code n'a aucun sens. Pourquoi à l'aide de l'aide de
Parallel.ForEach
sur list_lines_acc si vous n'utilisez pas les éléments de l'énumération vous itération, ni à l'aide de la ParallelLoopState paramètre?OriginalL'auteur SilverLight | 2012-09-24
Vous devez vous connecter pour publier un commentaire.
Dans votre code, comme l'écrit, chaque thread est en utilisant le même fichier, et tentent effectivement de s'y ajouter. Même si cela pourrait fonctionner, vous avez une mauvaise condition de course (comme le fils serait d'essayer de joindre le même fichier en même temps).
L'erreur que vous voyez est uniquement parce que vous êtes en utilisant le même fichier dans chaque itération de boucle, de sorte que lorsque vous essayez d'ouvrir le fichier (après la première itération), c'est erroring arrière comme il est ouvert par un autre itération de boucle.
Aussi, vous n'êtes jamais à l'aide de votre variable de boucle (
line_acc
), donc il n'y a vraiment pas besoin d'une boucle ici. Cela pourrait être écrit sans laParallel.ForEach
, et vous avez le même résultat, sans aucun problème.Cela étant dit, si c'est un exemple de code, vous aurez tendance à trouver que les boucles qui sont liés uniquement par fichier I/O aura tendance à ne pas paralléliser. Le lecteur réel utilisé deviendra le facteur limitant, afin d'exécuter du code que purement lit et écrit dans un fichier en parallèle sont souvent la cause de l'résultant du code de s'exécuter plus lentement, pas plus rapide, que de courir de façon séquentielle.
Le code dont vous faites preuve "pour l'exemple" est en train de faire rien de tout cela, il est donc difficile de voir où votre problème susceptible de se produire. Vous pouvez écrire sur un tableau ou
List<T>
par index, mais vous ne pouvez pas ajouter à une liste dans une boucle parallèle sans synchronisation supplémentaire (comme unlock
), commeList<T>
n'est pas thread-safe pour les écritures. Si vous essayez de lire et écrire à partir de collections, vous pourriez envisager de regarder laSystem.Les Collections.Simultanées
espace de noms qui contient thread-safe collections, vous pouvez utiliser en toute sécurité dansParallel.ForEach
boucles.OriginalL'auteur Reed Copsey
Comme indiqué dans cette question:
l'intention de la réponse est d'informer les OP qu'un index est la bonne façon d'éviter ces problèmes. J'aurais suggéré un mutex, mais je ne sais pas si une primitive est nécessaire pour résoudre son problème.
Index de quoi? Il n'y a pas d'indice là maintenant, comment l'ajout d'un index d'aide?
L'ajout d'un index pour accéder correctement à chaque fichier dans le but serait d'empêcher le blocage des questions que l'OP est en train de vivre. Faire un
ForEach
implique que l'objet sur lequel l'opération est en cours est IEnumerable, qui est à plaquettes indexables.Est-il une autre question que l'OP a demandé? Cette question est au sujet de "fichier en cours d'utilisation", n'est pas mort de verrouillage. Et de faire respecter l'ordre est à l'opposé de "Parallèle". Si l'ordre des opérations est important (cette question n'a pas de détails), via Parallèle.* Serait une meilleure approche... Rien détaillées ferait n'importe quoi.w.r.t de l'ordre avec l'OP du code.
OriginalL'auteur Codeman
Utiliser un
lock
objet autour de la problématique de code.... L'exécution d'attente pour la libération du verrou et vous n'aurez jamais plusieurs threads accèdent à la ressource.... en parallèle ForEach ne sera pas ajouter de la performance dans ce cas . Voici un exemple simple:OriginalL'auteur Guish
Pour se débarrasser d'un fichier dans une erreur d'utilisation (en supposant qu'il est en cours d'utilisation, car un autre thread d'écriture), vous devez synchroniser l'accès au fichier. Cela signifie généralement que chaque exécution parallèle est en attente sur d'autres exécutions de terminer l'écriture et de défaites le but de s'exécuter en parallèle.
OriginalL'auteur Peter Ritchie