2016-09-09 1 views
0

Hallo und danke für Ihre Hilfe. Dieses Mal habe ich ein seltsames Problem mit einem Programm (C#) Ich schreibe und würde gerne Ihren Rat hören. Ich bin ein normales Programm (nicht multithreaded) schreiben, aber dann hinzugefügt auf einer Datei einen Timer (System.Timers.Timer)Timer, Dateien und Rennbedingungen?

Auch einen Stream Ich verwende zu schreiben. Ich öffne diese ähnliche

StreamWriter logStream=new StreamWriter(filename, true); 

was bedeutet, dass, wenn die Datei vorhanden ist, es hängt, wenn es nicht schafft.

Später schreibe ich in der Datei wie diese

logStream.WriteLine(message); 

Allerdings schreibe ich sowohl auf den Strom von die Hauptfunktion und der Funktion, die durch den Timer aufgerufen wird.

die Problemsymptome

Mein Programm einen Fehler wirft manchmal, wenn ich den Strom spülen oder schreiben Sie sagen, dass und zu anderen Zeiten „Kein Zugriff auf eine geschlossene Textwriter„keine geschlossene Datei zugreifen kann“... (Was ist ein „Textwriter“?)

jedoch merkwürdig, hält die Datei ohne Probleme geschrieben werden. (Auch die „kann nicht eine geschlossene Datei zugreifen“ Nachricht wird in der vermeintlichen geschlossenen Datei geschrieben)

ich bin nicht vertraut mit der inneren Funktionsweise eines Timers. (Ich nehme an, es läuft ein sep arate Faden?)

Meine Frage ist

Ist es möglich, eine Stream von mehreren Threads zu verwenden? (in diesem Fall der Haupt und der Timer) Ist es möglich, dass es eine Race Condition oder ein solches Problem gibt?


Eine weitere Sache: Ich machte einen logischen Fehler und schließen und öffnen Sie die Datei jedes Mal, wenn ich auf sie schreiben wollen. Ja, es ist ein Fehler und ich sollte es korrigieren. Aber vielleicht, wenn ich das korrigiere, verschwindet der Fehler, den ich oben beschrieben habe, einen schwerwiegenderen Fehler.

Mein Verdacht ist, dass ich da bin Schließen und Öffnen der Datei jeder Mal, wenn ich auf sie zu schreiben, vielleicht die beiden Threads versuchen, werden sie auf eine falsche Zeit für den Zugriff auf

Jede Hilfe sehr

+0

Zu einer Ihrer Fragen: Ein StreamWriter ist ein bestimmter TextWriter. –

+2

Versuchen Sie eine Protokollimplementierung zu erstellen? Warum benutzt du nicht?NET-integrierte Diagnose-API oder eine Logging-Bibliothek wie log4net? Protokollierungsbibliotheken müssen Protokollanforderungen von mehreren Threads akzeptieren, schreiben jedoch alle Einträge korrekt, ohne die Protokolldatei zu beschädigen. –

Antwort

1
geschätzt werden

Das Schließen und Öffnen der Datei in diesem Szenario führt zu einer Race Condition, wie Sie sie vermuten. Sie können den Stream nicht offen lassen und das Objekt an den Thread übergeben, da Sie möglicherweise ein ähnliches Problem haben, wenn Sie von einem anderen Thread aus aufrufen. Ihre beste Lösung bleibt eine thread-sichere Methode, die schreibt, was Sie an sie senden.

Die Methoden sind statisch, da die Sperre von allen Instanzen der Klasse zugänglich sein muss.

private static ReaderWriterLockSlim readerWriterLockSlim = new ReaderWriterLockSlim(); 

public static void AppendToFile(string path, string text) 
{ 
    // Set to locked (other thread will freeze here until object is unlocked 
    readerWriterLockSlim.EnterWriteLock(); 

    try 
    { 
     // Write that will append to the file 
     using (StreamWriter sw = File.AppendText(path)) 
     { 
      // append the text 
      sw.WriteLine(text); 
      sw.Close(); 
     } 
    } 
    finally 
    { 
     // Clear the lock 
     readerWriterLockSlim.ExitWriteLock(); 
    } 
} 
+1

Besser noch, verwenden Sie eine Protokollierungsbibliothek. Oder ein ActionBlock , der Nachrichten aus mehreren Threads in die Warteschlange stellt und sie einzeln mit einem einfachen Writer schreibt –