我正在尝试读取LAN上远程PC上的Windows更新日志。大多数时候我可以成功读取文件,但有时程序会锁定。可能由于一个或另一个问题 - 并不重要。我需要的是一种在Filestream / Streamreader锁定时恢复的方法 - 我不确定是哪个导致锁定。某些流可以设置超时,但下面的文件流在.CanTimeout调用时返回False。
如果流锁定,我怎么能突破? (有时锁是如此紧,需要关闭电源才能恢复。)
在实际尝试读取之前,有没有办法测试流是否会失败?
是否有其他方法可以读取另一个程序已打开的远程日志文件? (我正在使用stream方法,因为常规的File.IO被阻止,因为该文件在远程PC上是打开的。)
我越来越接近(我认为)这段代码。我浏览了引用帖子中的pathExists代码,但它是OP而不是答案。
Imports System.IO
Import System.Threading
...
Function GetAULog(PCName As String) As String
Try
Dim sLogPath As String = String.Format("\\{0}\c$\Windows\SoftwareDistribution\ReportingEvents.log", PCName)
If PCName = My.Computer.Name Then
sLogPath = String.Format("C:\Windows\SoftwareDistribution\ReportingEvents.log", PCName)
End If
' read file open by another process
If Not pathExists(sLogPath) Then
MsgBox("AU log file not found - PC on?")
Return "NA"
End If
Using fs As New FileStream(sLogPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
Using sr As New StreamReader(fs)
Dim s As String = sr.ReadToEnd
Return s
End Using
End Using
Catch ex As Exception
MsgBox(ex.Message)
Return ""
End Try
End Function
Public Function pathExists(path As String) As Boolean
Dim exists As Boolean = True
Dim t As New Thread(New ThreadStart(Sub() exists = System.IO.File.Exists(path)))
t.Start()
Dim completed As Boolean = t.Join(500)
'half a sec of timeout
If Not completed Then
exists = False
t.Abort()
End If
t = Nothing
Return exists
End Function
至少在PC关闭时,pathExists()代码会在短时间内返回False。
现在我的问题是当程序退出时进程没有结束 - 至少在IDE中,没有检查运行时。
我添加了t = Nothing
,但这没有帮助。我无法找出正确的Using语法来测试它。 如何在线程超时后正确清理?
答案 0 :(得分:0)
我遇到了这种锁定的情况,直到重启问题。它似乎是由tcpip自动调整功能引起的。您可以通过运行
来解决此问题netsh interface tcp set global autotuninglevel=disable
如果您有权访问,请在两台计算机上运行此操作。我尝试了一些解决锁等问题的解决方法,但我能解决的唯一方法就是禁用它。问题不在于锁定,而是在文件共享协议中处于较低级别。
答案 1 :(得分:0)
"最终"代码如下所示。超时发生时不会触发异常,因此.Abort
显然是正常的。
当发生超时时,因为远程PC没有响应,所以有一个挂起的进程在30秒左右后消失。我在使用IDE时注意到这一点,我运行程序并测试关闭的PC。如果我然后退出程序表单关闭但IDE挂起约30秒 - 我可以在此点单击Stop-Debugging并且它可以正常工作,但IDE会在~30秒超时后自行继续。
我想finally块中的t = Nothing
没有处理该线程。 t.Dispose
不存在。
所以,除了最终清除自己的悬空线程之外,事情正常。该程序不再悬而未决,无法停止。
'Imports System.IO
'Imports System.Threading
Public Function pathExists(path As String) As Boolean
' check for file exists on remote PC
Dim exists As Boolean = False
Dim t As New Thread(New ThreadStart(Sub() exists = System.IO.File.Exists(path)))
Try
t.Start()
Dim completed As Boolean = t.Join(500)
'half a sec of timeout
If Not completed Then
exists = False
t.Abort()
End If
Catch ex2 As ThreadInterruptedException
MsgBox("timeout on AU log exists test" & vbNewLine & ex2.Message,, "ThreadInterruptedException")
Catch exAbort As ThreadAbortException
MsgBox("timeout on AU log exists test" & vbNewLine & exAbort.Message,, "ThreadAbortException")
Catch ex As Exception
MsgBox("exception on AU log exists test" & vbNewLine & ex.Message)
Finally
t = Nothing
End Try
Return exists
End Function