2016-09-09 3 views
0

Здравствуйте и спасибо за помощь. На этот раз у меня возникла любопытная проблема с программой (C#), которую я пишу, и хотел бы услышать ваш совет. Я пишу обычную программу (не многопоточную), но затем добавил таймер (System.Timers.Timer)Таймеры, файлы и условия гонки?

Также я использую StreamWriter для записи в файл. Я открываю это так:

StreamWriter logStream=new StreamWriter(filename, true); 

означает, что если файл существует, он добавляет, если он не создает.

Позже я пишу в файле, как этого

logStream.WriteLine(message); 

Однако, я пишу в поток из как основной функции и от функции, которая вызывается с помощью таймера.

проблемных симптомы

Моей программа бросает ошибку иногда когда я промывать или записать поток о том, что «не удается получить доступ к закрытому файлу» и другие времен «Не удается получить доступ к закрытой TextWriter ... (Что такое «TextWriter»?)

Однако любопытно, что файл продолжает быть написано без проблем. (Даже «не может получить доступ закрытого файла» сообщение записывается в предполагаемом закрытом файле)

Я не знакомы с внутренней работой таймера. (Я полагаю, что он запускает сеп arate нить?)

Мой вопрос

Можно ли использовать StreamWriter из нескольких потоков? (в этом случае основной и таймер один) Возможно ли, что происходит состояние гонки или какая-то проблема? более


одно: я сделал логическую ошибку и закрыть и повторно открыть файл каждый раз, когда я хочу, чтобы писать на нем. Да, это ошибка, и я должен ее исправить. Но, возможно, если я исправлю это, то описанная выше ошибка исчезнет, ​​маскируя более серьезный недостаток.

Мои подозрения в том, что, так как я закрытия и открытия файла каждый раз, когда я пишу на нем, может быть, оба потока пытаются получить доступ к ним в то время

Любая помощь будет высоко оценен

+0

К одному из ваших вопросов: StreamWriter - это специфический TextWriter. –

+2

Вы пытаетесь создать реализацию каротажа? Почему бы вам не использовать.NET встроенный диагностический API или библиотека регистрации, например log4net? Журнальные библиотеки должны принимать запросы журналов из нескольких потоков, но все записи записывать правильно, не повреждая файл журнала. –

ответ

1

Закрытие и открытие файла в соответствии с этим сценарием создаст состояние гонки, как вы подозреваете. Вы не можете сохранить поток открытым и передать объект в поток, потому что вы можете столкнуться с подобной проблемой, если вы вызываете из другого потока. Ваше лучшее решение остается с помощью метода потоковой безопасности, который будет писать то, что вы ему отправляете.

методы являются статическими, поскольку блокировка должна быть доступна из всех экземпляров класса.

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

Еще лучше, используйте библиотеку регистрации. Или ActionBlock , который ставит в очередь сообщения из нескольких потоков и записывает их один за другим с использованием простой записи –

Смежные вопросы