Возникла проблема с открытием/записью текстового файла в ASP.NET.

StackOverflow https://stackoverflow.com/questions/639406

  •  11-07-2019
  •  | 
  •  

Вопрос

Я хочу записывать статистику в текстовый файл каждый раз, когда человек загружает страницу.Но время от времени я получаю сообщение об ошибке типа «Не удалось открыть файл, уже используется».Я не могу на 100% повторить эту ошибку, она очень нестабильна.Мой код

Public Sub WriteStats(ByVal ad_id As Integer)
    Dim ad_date As String = Now.Year & Now.Month

    Dim FILENAME As String = Server.MapPath("text/BoxedAds.txt")
    Dim objStreamWriter As StreamWriter
    objStreamWriter = File.AppendText(FILENAME)
    objStreamWriter.WriteLine(ad_id & ";" & ad_date)
    objStreamWriter.Close()
End Sub

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

Спасибо

Это было полезно?

Решение

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

Если у вас слишком много конфликтов, возможно, имеет смысл записать их в таблицу в базе данных и создать процесс для экспорта в файл (если он все еще необходим).

Другие советы

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

Public Sub WriteStats(ByVal ad_id As Integer)
    Dim ad_date As String = Now.Year & Now.Month
    Dim FILENAME As String = Server.MapPath("text/BoxedAds.txt")
    Dim index As Integer

    Using fs As New IO.FileStream(FILENAME, IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.ReadWrite), _
          tl As New TextWriterTraceListener(fs)

        index = Trace.Listeners.Add(tl)
        Trace.WriteLine(ad_id & ";" & ad_date)
        Trace.Listeners(index).Flush()
        Trace.Flush()
    End Using
    Trace.Listeners.RemoveAt(index)
End Sub

Здесь три важные вещи:

  1. Использование IO.FileShare.ReadWrite для одновременной записи нескольких записей в файл.
  2. Оператор using, обеспечивающий немедленное закрытие потока даже в случае возникновения исключения.Это сведет к минимуму столкновения
  3. TextWriterTraceListener создаст для вас временный файл, если он не сможет открыть запрошенный вами файл, чтобы убедиться, что сообщение не потеряно.

У меня не было проблем с краткой информацией, используя:File.AppendAllText(путь, информация);

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top