4

Say I have some code that does this:

Public Function AppendToLogFile(ByVal s As String) As Boolean
    Dim success As Boolean = True
    Dim fs As IO.FileStream = Nothing
    Dim sw As IO.StreamWriter = Nothing

    Static LogFileLock As New Object()
    SyncLock LogFileLock
        Try
            fs = New IO.FileStream(LogFilePath)
            sw = New IO.StreamWriter(fs)
            sw.WriteLine(s)

        Catch ex As Exception
            success = False

        Finally
            If Not sw Is Nothing Then sw.Close()
            If Not fs Is Nothing Then fs.Close()
        End Try
    End SyncLock

    Return success
End Function

First of all: is it a problem that I have that Try/Catch/Finally block inside of a SyncLock?

Second of all: suppose this code runs, on an event, potentially many times within a small timeframe--say, ten times in one second. Is it OK to have it SyncLock like this, or would it make more sense to have it add a line to a Queue, and then write all the lines from the Queue to the file on a timer that goes off, say, every second?

4

2 回答 2

4

乍一看,这看起来不错,但有两个警告:

  1. 静态成员已经在幕后使用了一种线程安全的锁定。因此,您可能只能搭载现有锁,而不是显式锁。不过,我不确定那会是什么样子。
  2. 不要返回状态码。让异常传播到适当的级别。一旦你这样做了,你可以像这样重写你的代码:

.

Public Sub AppendToLogFile(ByVal s As String) As Boolean
    Static LogFileLock As New Object()
    SyncLock LogFileLock
        Using sw As New IO.StreamWriter(LogFilePath)
            sw.WriteLine(s)
        End Using
    End SyncLock
End Sub

这就是不到一半代码中的所有功能。唯一的区别是您必须在调用代码中处理异常,而不是检查返回状态。

于 2009-09-14T18:11:42.640 回答
4

在您的情况下,只要相对不频繁地写入日志文件,锁定就可以了。换句话说,如果每个成功的操作都写入日志,那可能不是一个好的设计。如果只有失败的操作写入日志,那么它可能绰绰有余。

此外,如果您经常写入此日志,您可能希望在共享变量中引用“StreamWriter”。

Public NotInheritable Class Log

    Private Shared m_LogLock As New Object
    Private Shared m_Log As StreamWriter

    Public Shared Sub WriteLog(ByVal message As String)
        SyncLock m_LogLock
            If m_Log Is Nothing Then
                m_Log = New StreamWriter("pathAndFileName")
            End If
            m_Log.WriteLine(message)
            m_Log.Flush()
        End SyncLock
    End Sub

End Class
于 2009-09-14T18:15:12.113 回答