文件流只读锁定PC
Filestream read only locking PC
我正在尝试读取我 LAN 上远程 PC 上的 Windows 更新日志。大多数时候我可以成功读取文件,但有时程序会锁定。可能是由于一个或另一个问题 - 并不重要。我需要的是一种在 Filestream/Streamreader 锁定时恢复的方法——我不确定是哪个导致了锁定。某些流可以设置超时,但下面的文件流 returns 在 .CanTimeout 调用时为 False。
流卡死了怎么破? (有时锁太紧需要断电才能恢复。)
有没有办法在我实际尝试读取之前测试流是否会失败?
有没有其他方法可以读取另一个程序打开的远程日志文件? (我正在使用流方法,因为常规 File.IO 被阻止,因为文件在远程 PC 上打开。)
我越来越接近(我认为)这个代码。我浏览了引用的 post 中的 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() 代码时 returns 短时间内为假。
我现在的问题是当程序退出时进程没有结束 - 至少在 IDE,没有检查运行时。
我添加了 t = Nothing
但这没有帮助。我无法找出正确的 Using 语法来测试它。 如何在线程超时后正确清理?
我遇到过这种锁定直到重启的问题。这似乎是由 tcpip 自动调整功能引起的。您可以通过 运行
解决此问题
netsh interface tcp set global autotuninglevel=disable
运行 如果您有权访问,请在两台计算机上执行此操作。我尝试了一些检查锁等问题的解决方法,但我能解决它的唯一方法是禁用它。问题不在于锁定,而在于文件共享协议中较低级别的内容。
"Final"代码如下所示。发生超时时不会触发异常,因此 .Abort
显然没问题。
当确实发生超时时,因为远程 PC 没有响应,所以有一个进程挂起并在 30 秒左右后消失。我在使用 IDE 时注意到这一点,我 运行 程序并测试了一台关闭的 PC。如果我然后退出程序,表单关闭但 IDE 挂起约 30 秒 - 我可以在此时单击停止调试并且它有效,但 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
我正在尝试读取我 LAN 上远程 PC 上的 Windows 更新日志。大多数时候我可以成功读取文件,但有时程序会锁定。可能是由于一个或另一个问题 - 并不重要。我需要的是一种在 Filestream/Streamreader 锁定时恢复的方法——我不确定是哪个导致了锁定。某些流可以设置超时,但下面的文件流 returns 在 .CanTimeout 调用时为 False。
流卡死了怎么破? (有时锁太紧需要断电才能恢复。)
有没有办法在我实际尝试读取之前测试流是否会失败?
有没有其他方法可以读取另一个程序打开的远程日志文件? (我正在使用流方法,因为常规 File.IO 被阻止,因为文件在远程 PC 上打开。)
我越来越接近(我认为)这个代码。我浏览了引用的 post 中的 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() 代码时 returns 短时间内为假。
我现在的问题是当程序退出时进程没有结束 - 至少在 IDE,没有检查运行时。
我添加了 t = Nothing
但这没有帮助。我无法找出正确的 Using 语法来测试它。 如何在线程超时后正确清理?
我遇到过这种锁定直到重启的问题。这似乎是由 tcpip 自动调整功能引起的。您可以通过 运行
解决此问题netsh interface tcp set global autotuninglevel=disable
运行 如果您有权访问,请在两台计算机上执行此操作。我尝试了一些检查锁等问题的解决方法,但我能解决它的唯一方法是禁用它。问题不在于锁定,而在于文件共享协议中较低级别的内容。
"Final"代码如下所示。发生超时时不会触发异常,因此 .Abort
显然没问题。
当确实发生超时时,因为远程 PC 没有响应,所以有一个进程挂起并在 30 秒左右后消失。我在使用 IDE 时注意到这一点,我 运行 程序并测试了一台关闭的 PC。如果我然后退出程序,表单关闭但 IDE 挂起约 30 秒 - 我可以在此时单击停止调试并且它有效,但 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