Filestream只读锁定PC

时间:2016-09-08 22:07:15

标签: vb.net multithreading filestream streamreader

我正在尝试读取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语法来测试它。 如何在线程超时后正确清理?

2 个答案:

答案 0 :(得分:0)

我遇到了这种锁定的情况,直到重启问题。它似乎是由tcpip自动调整功能引起的。您可以通过运行

来解决此问题
netsh interface tcp set global autotuninglevel=disable

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

See this article for more detail

答案 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