写入文本文件,另一个进程使用的文件,多线程应用程序.NET

时间:2015-01-14 15:25:35

标签: vb.net multithreading

下午,

我有一个程序,我真的需要保存某种日志以确定程序正在做什么。本质上,软件监视桌面上的窗口,以便在我们的Call Recorder服务器上暂停通话记录。

让我们在争论中说,一个监听代理人已经拨打了一个电话录音本身,他们表示,当他们真的应该沉默时,会话的某个敏感部分被记录下来,如果他们说代理人没有&#39完成了他们的工作并点击了暂停录制按钮或者没有发生onfocus动作我会遇到这样的情况:我需要证明软件在同一时间做了什么。

我决定将软件的操作写入存储在用户应用数据中的.txt文件。

这在大多数情况下都有效,但是偶尔也会出现.txt永远不会被任何其他程序访问。这个文件正由另一个进程使用'。

这个应用程序是多线程的,并且非常频繁地调用写入日志,我使用下面的代码:

Private Sub WriteToLog(ByVal strSubTitle As String, ByVal strLogInfo As String)

    Try
        If My.Computer.FileSystem.FileExists(strLogFilePath) = True Then

            'Delete yesterdays log file
            Dim strFileDate As Date = File.GetCreationTime(strLogFilePath)
            strFileDate = FormatDateTime(strFileDate, DateFormat.ShortDate)

            'If strFileDate < Date.Today Then
            '    My.Computer.FileSystem.DeleteFile(strLogFilePath)
            'End If

            Using outFile As IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(strLogFilePath, True)

                outFile.WriteLine("" & Date.Today & "," & Date.Now.ToLongTimeString & ", " & strUsername & ", " & strSubTitle & ", " & Replace(strLogInfo, ",", "|") & "")
                outFile.Close()

            End Using
            ''CSV File
            'outFile.WriteLine("" & Date.Today & "," & Date.Now.ToLongTimeString & ", " & strUsername & ", " & strSubTitle & ", " & Replace(strLogInfo, ",", "|") & "")
            'outFile.Close()

        Else

            Using outFile As IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(strLogFilePath, False)

                outFile.WriteLine("" & Date.Today & "," & Date.Now.ToLongTimeString & ", " & strUsername & ", " & strSubTitle & ", " & Replace(strLogInfo, ",", "|") & "")
                outFile.Close()

            End Using
            'CSV File
            'outFile.WriteLine("Date, Time, Username, Sub(Process), Information")
            'outFile.WriteLine("" & Date.Today & "," & Date.Now.ToLongTimeString & ", " & strUsername & ", " & strSubTitle & ", " & Replace(strLogInfo, ",", "|") & "")
            'outFile.Close()

        End If

    Catch ex As Exception
        CreateErrorFile(ex.Message, ex.StackTrace, "Log Write Failure!")
    End Try

End Sub

是否有任何建议/指示可以说明为什么这会说另一个进程正在使用该文件。

我猜测当两个独立的线程尝试执行&#39; WriteToLog&#39;时会发生这种情况。 Sub,而其中一个正在写入文件。

我是否在正确的轨道上?如果是这样,我怎么能纠正这个?

干杯,

詹姆斯

2 个答案:

答案 0 :(得分:0)

您要么想要使它只有一个线程能够通过使用辅助线程中的Invoke方法来写入日志文件来调用主线程上的写入功能,或者您可以使用.NET的各种同步机制之一。

以下是第一种方法的简单示例:

Private Sub BackgroundMethod()
    'do stuff
    Me.Invoke(New Action(Of String)(AddressOf WriteToLog), "write a line blah blah")
    'do more stuff
End Sub

Private Sub WriteToLog(valueToWrite As String)
    System.IO.File.AppendAllLines(MyLogFilePath, {valueToWrite})
End Sub

以下是使用SyncLock块的示例:

Private lock As New Object()

Private Sub BackgroundMethod()
    'do stuff
    WriteToLog("write a line blah blah")
    'do more stuff
End Sub

Private Sub WriteToLog(valueToWrite As String)
    SyncLock (lock)
        System.IO.File.AppendAllLines(MyLogFilePath, {valueToWrite})
    End SyncLock
End Sub

MSDN有关于同步机制的良好信息:http://msdn.microsoft.com/en-us/library/ms228964%28v=vs.110%29.aspx

答案 1 :(得分:0)

我会使用全局队列添加新条目,如果日志编写器不忙,则启动它以记下所有可用行。

喜欢:

  Private LogList As New Queue(Of String)
  Private WriterBusy As Boolean = False

  Private Sub WriteToLog(ByVal strSubTitle As String, ByVal strLogInfo As String)

    LogList.Enqueue("" & Date.Today & "," & Date.Now.ToLongTimeString & ", " & strUsername & ", " & strSubTitle & ", " & Replace(strLogInfo, ",", "|") & "")

    If WriterBusy = True Then Exit Sub
    WriterBusy = True

    Try
        If My.Computer.FileSystem.FileExists(strLogFilePath) = True Then
        ...

        Using outFile As IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(strLogFilePath, True)

          While LogList.Count > 0 
              outFile.WriteLine(LogList.Dequeue)
          End While
          outFile.Close()

        End Using
        ...
    End Try

    WriterBusy = False

  End Sub