2010-04-22 7 views
3

Supposons que vous ayez un fichier dans lequel vous consignez par programme des informations relatives à un processus. Un peu comme votre débogage type Console.WriteLine, mais en raison de la nature du code que vous testez, vous n'avez pas de console à écrire, vous devez donc l'écrire quelque part comme un fichier. Mon programme actuel utilise System.IO.StreamWriter pour cette tâche.Ouverture et fermeture rapides System.IO.StreamWriter en C#

Ma question concerne l'approche d'utilisation de StreamWriter. Est-il préférable d'ouvrir une seule instance de StreamWriter, de faire toutes les écritures et de la fermer lorsque tout le processus est terminé? Ou est-ce une meilleure idée d'ouvrir une nouvelle instance de StreamWriter pour écrire une ligne dans le fichier, puis de la fermer immédiatement, et de le faire à chaque fois que quelque chose doit être écrit? Dans la seconde approche, cela serait probablement facilité par une méthode qui ferait exactement cela pour un message donné, plutôt que de gonfler le code de processus principal avec des quantités excessives de lignes. Mais avoir une méthode pour aider à cette mise en œuvre ne fait pas nécessairement le meilleur choix. Y a-t-il des avantages significatifs à choisir une approche ou l'autre? Ou sont-ils fonctionnellement équivalents, laissant le choix sur les épaules du programmeur?

+1

Jetez un coup d'œil à la redirection de la sortie standard (par exemple Console.SetOut). http://msdn.microsoft.com/en-us/library/system.console.setout.aspx – gooch

Répondre

0

L'ouverture/fermeture répétée d'un nouveau StreamWriter pour chaque écriture générera beaucoup de ressources pour le GC et imposera une surcharge à l'application en raison de la recherche réelle du fichier pour chaque opération ouverte. D'un autre côté, si vous maintenez un seul flux ouvert, vous pourrez verrouiller le fichier. Cela dépend donc. Vous ne voulez pas que votre mécanisme de journalisation devienne un goulot d'étranglement au niveau des performances, alors écrivez dans un seul flux. Faites-le sans tampon ou AutoFlush pour le débogage critique (mais sachez que cela a également un impact sur les performances). Je suivrais le modèle de log4net, créerais un flux de journal statique, et écrirais à ce singleton. Regardez dans log4net de toute façon, donc vous ne roulez pas les vôtres. http://logging.apache.org/log4net/index.html

+0

Le commentaire de OregonGhost résout réellement ma situation. Mais ce n'est pas une réponse ... donc je ne peux pas l'accepter. Cette réponse, pour le caractère plus général de la question, explique explicitement les différences dans les approches, donc je vais accepter celle-ci. –

4

Regardez les implémentations de journalisation pré-roulées; ils peuvent vous épargner beaucoup de maux de tête. De toute évidence, si vous gardez le flux ouvert, vous risquez de perdre certaines des données de fin si elles tombent en panne, mais cela peut augmenter les performances de la mise en mémoire tampon des E/S. Certaines implémentations peuvent également offrir des fonctionnalités telles que la journalisation asynchrone à partir d'un spouleur/file d'attente.

+0

@Marc: Buffering devrait être un problème distinct. Un flux ouvert peut être un flux AutoFlush (ou potentiellement non tamponné). Je suppose que System.Console.Error utilise AutoFlush, car c'est la tradition pour le handle "stderr". – codenheim

+0

@Marc Ne soyez pas fainéants, mais avez-vous des recommandations de haut niveau pour des solutions de journalisation particulièrement efficaces? J'ai regardé la suggestion de @mrjoltcola mais je me dis que c'est toujours bon d'étaler la recherche. Et à cette fin, même si je ferai d'autres recherches par moi-même, si vous aviez des suggestions immédiates à examiner, ce serait pratique. –

1

Je tampon/file d'attente les données & écrire dans le fichier une fois qu'il atteint un seuil & vider la file d'attente ensemble lorsque l'application ferme/sort normalement.

La seule question en litige est dans le cas d'un plantage de l'application, vous risquez de perdre les éléments de la file d'attente ...

HTH.

+0

Je pense que la perte de données sur le plantage de l'application peut être critique si vous utilisez le journal pour déboguer un tel plantage, plutôt que de vous connecter à l'utilisateur.Dans ce dernier cas, la solution tampon est sûrement meilleure, d'autant plus que votre solution ne verrouille pas le fichier tout le temps, donc c'est un +1. – OregonGhost

+0

@OregonGhost, si je débogue des plantages, je vais définir mon seuil pour écrire le fichier pour chaque 1-2 entrées dans la file d'attente. Dans une application normale en cours d'exécution, je pourrais le configurer pour écrire pour 100 entrées. Je ne pense pas que la performance de l'application soit un facteur clé au moment du débogage, mais elle est importante lors d'une exécution en direct. – Sunny

+0

@Sunny: Si je regarde les grandes applications de bureau de mon entreprise, la journalisation, même immédiatement, n'a jamais été pertinente pour les performances (et oui, j'ai profilé (;). Le système d'exploitation mettra également en cache les données d'écriture. , Je vais au moins avoir tous les messages d'erreur, y compris les traces de pile du tout premier crash, nous avons eu des plantages qui étaient difficiles à reproduire (en fonction de facteurs externes, surtout), et cela a été très utile dans beaucoup de cas. Mais surtout, si vous consignez beaucoup de choses, je suppose que c'est la différence entre un journal d'erreurs pur et un journal général – OregonGhost

Questions connexes