У меня проблемы с корректным закрытием дескриптора файла.Я попытался использовать дополнительный Mutex
, чтобы гарантировать, что только один поток имеет доступ к этому файлу за один раз.
Насколько я понимаю, конструкция Using
должна обеспечивать правильное освобождение дескриптора файла.и Mutex
должен гарантировать, что этот код может выполняться только в 1 потоке за раз.
Ошибка возникает, когда регистратор вызывается несколько раз в быстрой последовательности.
Gethashcode былпопытка проверить, совпадает ли экземпляр мьютекса.
Сообщение об ошибке:
Произошло необработанное исключение типа 'System.IO.IOException' в mscorlib.dll
Процесс не может получить доступ к файлу «**** \ LOG.log», поскольку он используется другим процессом.
Источник:
Imports System.IO
Imports System.Net.Mail
Imports System.Threading
Public NotInheritable Class FileLogger
Private Shared ReadOnly _instance As New Lazy(Of FileLogger)(Function() New FileLogger(), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication)
Public LOG_LEVEL As Integer = 4
Public LEVELS As New Dictionary(Of Double, String)
Private Shared strFile As String = "LOG.log"
Public Shared FileLoc As New Mutex()
Public Shared ReadOnly Property getLogger() As FileLogger
Get
Return _instance.Value
End Get
End Property
Private Sub New()
Dim strFile As String = "yourfile.log"
LEVELS.Add(0, "FATAL ")
LEVELS.Add(1, "CRITICAL")
LEVELS.Add(2, "ERROR ")
LEVELS.Add(3, "INFO ")
LEVELS.Add(4, "DEBUG ")
LEVELS.Add(2.5, "WARNING ")
End Sub
Public Sub writeEntry(ByVal message As String, ByVal level As Double)
If level <= LOG_LEVEL Then
Dim log_str As String = String.Format("{0} - in: {3} - {1}: {2}", DateTime.Now.ToString, LEVELS(level), message, Thread.CurrentThread.ManagedThreadId)
Console.WriteLine(log_str)
If level < 3 Then ' warning or greater write to file else just console
Console.WriteLine(FileLoc.GetHashCode())
FileLoc.WaitOne(Timeout.Infinite)
Using sw As StreamWriter = New StreamWriter(strFile, True) '<-- Debugger points to this line
sw.WriteLine(log_str)
End Using
FileLoc.ReleaseMutex()
End If
If level <= 2 Then 'if error or greater send email
FileLoc.WaitOne(Timeout.Infinite)
Dim mail As New MailMessage
mail.To.Add("email")
mail.From = New MailAddress("email")
mail.Subject = "Error on MC Server (SERVERNAME)"
mail.Body = log_str
mail.IsBodyHtml = True
mail.Attachments.Add(New Attachment(strFile))
Dim smtp As New SmtpClient
smtp.Host = "IPADDR"
smtp.Send(mail)
FileLoc.ReleaseMutex()
End If
End If
End Sub
End Class