互斥锁没有锁定并且没有释放文件句柄

时间:2018-06-13 10:35:38

标签: vb.net multithreading mutex

我无法正常关闭文件句柄。我尝试使用额外的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

1 个答案:

答案 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
相关问题