2016-09-08 27 views
0

我正在尝试读取局域网上远程PC上的Windows更新日志。大多数情况下,我可以成功读取文件,但有时程序锁定。可能由于某个问题或另一个问题 - 并不重要。我所需要的是一种在Filestream/Streamreader锁定时恢复的方法 - 我不确定是哪一个导致锁定。有些流可以设置超时,但下面的文件流在.CanTimeout调用上返回False。Filestream只读锁定PC

如何锁定流锁定? (有时锁是如此之紧以致需要关闭电源才能恢复。)

有没有一种方法可以在我实际尝试读取之前测试流是否会失败?

是否有另一种方法来读取另一个程序已打开的远程日志文件? (我使用的是流的方法,因为正规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但这没有帮助。我无法弄清楚正确的使用语法来测试。 线程超时后如何正确清理?

回答

0

如下所示的 “最终” 的代码。当超时发生时异常不会触发,所以.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 
0

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

netsh interface tcp set global autotuninglevel=disable 

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

See this article for more detail

+0

这可能不是我的问题,因为文件(如果存在的话)(我需要更改我的代码以检查Exists)是合理的大小。它似乎挂在连接时间。 Exists可能会暴露连接问题,并希望超时。 – rheitzman

+0

当我遇到问题时,无论是大文件还是小文件都无所谓。我们正在使用脚本将.net应用程序推送到30个不同的机器。间歇性地,这些机器中的少数将会有文件共享锁定,直到重新启动完成。用上面提到的这种方法修复它。 – FloatingKiwi

+0

我真的没有很好的机会访问目标机器,所以我需要更多的通用解决方案。 – rheitzman