我无法正常关闭文件句柄。我尝试使用额外的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
答案 0 :(得分:0)
电子邮件部分未正确关闭文件。将它包装在using构造中修复了该问题。
我最终还是围绕整个操作实现了SyncLock
构造。
正如一些评论所指出的那样,互斥体可能已经或可能没有按预期进行,但文件句柄仍然是从附件操作中打开的。
Public Sub writeEntry(ByVal message As String, ByVal level As Double)
SyncLock FileLoc
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())
Using sw As StreamWriter = New StreamWriter(strFile, True)
sw.WriteLine(log_str)
End Using
End If
If level <= 2 Then 'if error or greater send email
Using at As Attachment = New Attachment(strFile)
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(at)
Dim smtp As New SmtpClient
smtp.Host = "IPADDR"
smtp.Send(mail)
End Using
End If
End If
End SyncLock
End Sub