下午,
我有一个程序,我真的需要保存某种日志以确定程序正在做什么。本质上,软件监视桌面上的窗口,以便在我们的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,而其中一个正在写入文件。
我是否在正确的轨道上?如果是这样,我怎么能纠正这个?
干杯,
詹姆斯
答案 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