文件流只读锁定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

运行 如果您有权访问,请在两台计算机上执行此操作。我尝试了一些检查锁等问题的解决方法,但我能解决它的唯一方法是禁用它。问题不在于锁定,而在于文件共享协议中较低级别的内容。

See this article for more detail

"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