System.IO.IOException:进程无法访问该文件

时间:2015-03-21 08:43:24

标签: vb.net

嗨程序员同事们! 希望你知道如何解决我的问题。在写入我的日志文件时,时不总是得到像主题一样的错误。我的解决方案中有3个Windows服务。每个人都使用相同的文件来记录日志。不幸的是我不时得到错误。我的记录器代码如下所示。我使用了synlock,并认为这样就足够了,但有时候不行。你能帮助我改变一下以避免这个问题吗?:

Public NotInheritable Class Logger

    Private Shared ReadOnly _locker As New Object()

    Public Shared Sub LogIt(ByVal engine As String, ByVal msg As String, ByVal logMessage As String, ByVal Path As String, ByVal IsDebug As Boolean)


            If File.Exists(Path) Then
                If IsDebug Then
                    Debug.Print(DateTime.Now & "> " & "| " & engine & " | " & msg & " | " & logMessage)
                    ' Debug.Print(message)
                Else
                    SyncLock _locker


                        Using w As TextWriter = File.AppendText(Path)

                            'w.WriteLine(message)
                            w.WriteLine(DateTime.Now & "> " & "| " & engine & " | " & msg & " | " & logMessage)
                            w.Flush()
                        End Using
                    End SyncLock
                End If
            Else
                If IsDebug Then
                    '  Debug.Print(message)
                    Debug.Print(DateTime.Now & "> " & "| " & engine & " | " & msg & " | " & logMessage)
                Else
                    SyncLock _locker
                        Using w As TextWriter = File.CreateText(Path)
                            '   w.WriteLine(message)
                            w.WriteLine(DateTime.Now & "> " & "| " & engine & " | " & msg & " | " & logMessage)
                            w.Flush()
                        End Using
                    End SyncLock
                End If
            End If
        End Sub

end class

更新:

Imports System.IO
Imports System.Threading

Public NotInheritable Class Logger

    Private Shared ReadOnly _locker As New Mutex(False, "Global\AnyHardToGuessName")


  Public Shared Sub LogIt(ByVal engine As String, ByVal msg As String, ByVal logMessage As String, ByVal Path As String, ByVal IsDebug As Boolean)


        _locker.WaitOne()

        Try
            If File.Exists(Path) Then
                If IsDebug Then
                    Debug.Print(DateTime.Now & "> " & "| " & engine & " | " & msg & " | " & logMessage)
                    ' Debug.Print(message)
                Else
                        Using w As TextWriter = File.AppendText(Path)

                            'w.WriteLine(message)
                            w.WriteLine(DateTime.Now & "> " & "| " & engine & " | " & msg & " | " & logMessage)
                            w.Flush()
                        End Using
                End If
            Else
                If IsDebug Then
                    '  Debug.Print(message)
                    Debug.Print(DateTime.Now & "> " & "| " & engine & " | " & msg & " | " & logMessage)
                Else
                        Using w As TextWriter = File.CreateText(Path)
                            '   w.WriteLine(message)
                            w.WriteLine(DateTime.Now & "> " & "| " & engine & " | " & msg & " | " & logMessage)
                            w.Flush()
                        End Using
                End If
            End If

        Finally
            _locker.ReleaseMutex()
        End Try

    End Sub

End Class

1 个答案:

答案 0 :(得分:1)

  

我的解决方案中有3个Windows服务

产生3个单独的EXE,它们共享_locker对象。 .NET对象的可见性仅限于创建它们的过程。因此,没有什么能阻止这些程序同时尝试打开日志文件。或者尝试同时创建日志文件,你有一个File.Exists用法的错误,它也必须在SyncLock语句中,以防止两个线程同时检查文件存在时的竞争。

到目前为止,最好的解决方案是让每个EXE使用自己的日志文件,以便_locker对象足够好。如果共享绝对必要,那么您必须使用命名的Mutex来允许这些程序跨进程边界共享同一个同步对象。换句话说:

 Private Shared ReadOnly _locker As New Mutex(False, "Global\AnyHardToGuessName")

     Public Shared Sub LogIt(...)
        _locker.WaitOne()
        Try
            ''...
        Finally
            _locker.ReleaseMutex()
        End Try
     End Sub

在源文件的顶部添加Imports System.Threading