L'écriture dans le fichier dans un thread de manière sûre
Écrit Stringbuilder
de fichier en mode asynchrone. Ce code prend le contrôle d'un fichier, écrit un ruisseau et la libère. Il traite les demandes des opérations asynchrones, ce qui peut venir à tout moment.
La FilePath
est définie par instance de classe (de sorte que le verrou Object
est par exemple), mais il existe un potentiel de conflit depuis ces classes peuvent partager FilePaths
. Ce genre de conflit, ainsi que tous les autres types de l'extérieur de l'instance de classe, serait traitée avec de nouvelles tentatives.
Est ce code approprié pour ses fins? Est-il une meilleure façon de gérer ce qui signifie moins (ou pas) l'utilisation de la capture et de réessayer de mécanicien?
Aussi comment puis-je éviter d'attraper les exceptions qui ont eu lieu pour d'autres raisons.
public string Filepath { get; set; }
private Object locker = new Object();
public async Task WriteToFile(StringBuilder text)
{
int timeOut = 100;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (true)
{
try
{
//Wait for resource to be free
lock (locker)
{
using (FileStream file = new FileStream(Filepath, FileMode.Append, FileAccess.Write, FileShare.Read))
using (StreamWriter writer = new StreamWriter(file, Encoding.Unicode))
{
writer.Write(text.ToString());
}
}
break;
}
catch
{
//File not available, conflict with other class instances or application
}
if (stopwatch.ElapsedMilliseconds > timeOut)
{
//Give up.
break;
}
//Wait and Retry
await Task.Delay(5);
}
stopwatch.Stop();
}
oui, il y avait au départ, mais vous ne devriez pas attendre de choses dans une serrure, donc j'ai dû le changer. Je ne sais pas dans quelle mesure qui porte atteinte à l'ensemble de la chose.
Cela sonne comme il devrait être sur codereview tbh
Peut-être. Merci pour votre aide en tout cas.
Il existe d'autres Processus trhat pourrait accès Chemin d'accès? Parce que pour la seule application de la simultanéité vous pouvez supprimer la plupart de code.
OriginalL'auteur Nathan Cooper | 2014-05-07
Vous devez vous connecter pour publier un commentaire.
Façon dont vous vous approchez cela va beaucoup dépendre de la fréquence à laquelle vous écrivez. Si vous êtes en train de rédiger une petite quantité de texte assez fréquemment, alors il suffit d'utiliser un statique de verrouillage et être fait avec elle. Qui pourrait être votre meilleur pari en tout cas, car le disque dur ne peut que satisfaire une requête à la fois. En supposant que tous vos fichiers de sortie sont sur le même disque (peut-être pas une hypothèse juste, mais garder avec moi), il n'y a pas beaucoup de différence entre le verrouillage au niveau de l'application et de la serrure qui est fait au niveau de l'OS.
Donc, si vous déclarez
locker
:Vous serez assuré qu'il n'y a pas de conflits avec d'autres threads dans votre programme.
Si vous voulez que cette chose à l'épreuve des balles (ou au moins dans une mesure raisonnable), vous ne pouvez pas aller loin de l'interception d'exceptions. De mauvaises choses peuvent arriver. Vous doit gérer les exceptions, d'une certaine façon. Ce que vous faites dans le visage de l'erreur est tout autre chose. Vous aurez probablement envie de réessayer quelques fois si le fichier est verrouillé. Si vous obtenez un mauvais chemin ou le nom de fichier d'erreur ou disque plein ou d'un certain nombre d'autres erreurs, vous voulez probablement à tuer le programme. Encore une fois, c'est à vous. Mais vous ne pouvez pas éviter la manipulation d'exception, sauf si vous êtes d'accord avec le programme s'écraser sur erreur.
Par la manière, vous pouvez remplacer l'ensemble de ce code:
Avec un seul appel:
En supposant que vous êtes en utilisant .NET 4.0 ou version ultérieure. Voir Fichier.AppendAllText.
Une autre façon de gérer cela est d'avoir les discussions écrire leurs messages d'une file d'attente, et ont un thread dédié que les services de la file d'attente. Vous auriez un
BlockingCollection
de messages et de fichiers associés chemins. Par exemple:Votre threads écrire des données de la file d'attente:
Vous démarrez une tâche en arrière-plan qui ne fait rien mais le service que la file d'attente:
Votre potentiel de risque ici est que les threads créer des messages trop rapidement, ce qui provoque la file d'attente à croître sans limite parce que le consommateur ne peut pas suivre. Si c'est un risque réel dans votre application est quelque chose que vous pouvez dire. Si vous pensez qu'il pourrait y avoir un risque, vous pouvez mettre une taille maximale (nombre d'entrées) sur la file d'attente de sorte que si la taille de file d'attente dépasse cette valeur, les producteurs vont attendre jusqu'à ce que il ya de la place dans la file d'attente avant de pouvoir ajouter des.
Oh Monsieur, vous êtes grand.
OriginalL'auteur Jim Mischel
Vous pouvez également utiliser ReaderWriterLock, il est considéré comme plus "appropriées" moyen de contrôle de la sécurité des threads lorsqu'ils traitent de lire des opérations d'écriture...
Pour déboguer mes applications web (lorsque le débogage à distance échoue) - je utiliser à la suite de ('debug.txt' fin dans le dossier \bin sur le serveur):
Espère que cela vous fait gagner du temps.
ReaderWriterLock (et ReaderWriterLockSlim) sont pour les situations où vous avez besoin pour permettre à plusieurs lecteurs et un écrivain. Dans ce cas, si vous êtes en train d'écrire dans un fichier à partir de plusieurs threads, mais pas la lecture, je suggère simplement de verrouillage.
OriginalL'auteur Matas Vaitkevicius