2016-09-08 93 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