在SyncLock块中放置频繁的文件I / O操作是不是一个坏主意?

时间:2009-09-14 18:04:48

标签: .net vb.net file-io try-catch synclock

说我有一些代码可以做到这一点:

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

首先:我在SyncLock中有Try / Catch / Finally块吗?

其次:假设此代码在一个事件上运行,可能会在很短的时间内运行多次 - 比如说,在一秒钟内运行十次。让它像这样的SyncLock是否可以,或者让它在队列中添加一行更有意义,然后将所有行从队列写入到计时器上的文件,例如,每秒一次?

2 个答案:

答案 0 :(得分:4)

乍一看,这看起来没问题,有两点需要注意:

  1. 静态成员已在幕后使用一种线程安全锁定。因此,您可能只需要在现有锁上捎带,而不是显式锁定。不过,我不确定那会是什么样子。
  2. 不要返回状态代码。让异常传播到适当的级别。完成后,您可以像这样重写代码:
  3. 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
    

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

答案 1 :(得分: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