Блокировка файлов (чтение / запись) в приложении ASP.NET - PullRequest
2 голосов
/ 10 января 2009

У меня есть два веб-приложения ASP.NET. Один отвечает за обработку некоторой информации и запись в файл журнала , а другое приложение отвечает за чтение файла журнала и отображает информацию на основе запроса пользователя.

Вот мой код для писателя

public static void WriteLog(String PathToLogFile, String Message)
{
    Mutex FileLock = new Mutex(false, "LogFileMutex");
    try
    {
        FileLock.WaitOne();
        using (StreamWriter sw = File.AppendText(FilePath))
        {
            sw.WriteLine(Message);
            sw.Close();
        }    
    }
    catch (Exception ex)
    {
        LogUtil.WriteToSystemLog(ex);
    }
    finally
    {
        FileLock.ReleaseMutex();
    }
}

А вот мой код для Читателя:

private String ReadLog(String PathToLogFile)
{
    FileStream fs = new FileStream(
          PathToLogFile, FileMode.Open, 
          FileAccess.Read, FileShare.ReadWrite);
    StreamReader Reader = new StreamReader(fs);
    return Reader.ReadToEnd();
}

Мой вопрос, достаточно ли приведенного выше кода для предотвращения блокировки в среде web-сада?

РЕДАКТИРОВАТЬ 1: Грязное чтение в порядке. РЕДАКТИРОВАТЬ 2: Создание Mutex с новым Mutex (false, "LogFileMutex"), закрытие StreamWriter

Ответы [ 4 ]

7 голосов
/ 10 января 2009

Похоже, вы пытаетесь создать базовую очередь. Почему бы не использовать очередь, которая обеспечивает вам гарантированную доступность. Вы можете отправить сообщения в MSMQ, а затем внедрить службу Windows, которая будет читать из очереди и отправлять сообщения в БД. Если запись в БД завершается неудачно, вы просто оставляете сообщение в очереди (хотя вы захотите обработать почтовые сообщения, поэтому, если это не удастся из-за плохих данных, вы не окажетесь в бесконечном цикле)

Это избавит от всех проблем с блокировками и обеспечит гарантированную доставку вашему читателю ...

1 голос
/ 10 января 2009

Вы также должны избавиться от своего мьютекса, так как он происходит от WaitHandle, а WaitHandle реализует IDisposable:

using (Mutex FileLock = new Mutex(true, "LogFileMutex"))
{
    // ...
}

Кроме того, возможно, рассмотрим более уникальное имя (возможно, GUID), чем "LogFileMutex", поскольку другой не связанный процесс мог бы случайно использовать это же имя.

0 голосов
/ 10 января 2009

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

0 голосов
/ 10 января 2009

Делая это в веб-среде, у вас будет много проблем с блокировками файлов, можете ли вы изменить это на использование базы данных?

Большинство хостинговых решений поддерживают до 250 МБ баз данных SQL.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...