2016-09-08 25 views
0

LAN上のリモートPC上のWindowsアップデートログを読み込もうとしています。ほとんどの場合、ファイルを正常に読み取ることができますが、プログラムがロックされることがあります。 1つの問題または別の問題の可能性があります - 本当に重要ではありません。私が必要とするのは、Filestream/Streamreaderがロックアップしたときに回復する方法です。ロックを引き起こしているかどうかわかりません。いくつかのストリームはタイムアウトを設定できますが、以下のfilestreamは.CanTimeout呼び出しでFalseを返します。Filestream読み取り専用ロックPC

ストリームがロックアップした場合はどうすれば解除できますか? (時にはロックが強すぎるため、電源を切って復旧する必要があります)

実際に読み込みを試みる前にストリームが失敗するかどうかテストする方法はありますか?

別のプログラムが開いているリモートログファイルを読み取る別の方法はありますか? (ファイルがリモートPC上で開いているため、定期的なFile.IOがブロックされたので、私はストリーム方式を使用しています。)


を私はこのコードで(と思う)近づいています。私は参照されたポストから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秒間ハングします。この時点で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 
0

私は再起動の問題が発生するまでこのロックで状況を抱えています。これは、tcpipオートチューニング機能によって発生したようです。

netsh interface tcp set global autotuninglevel=disable 

アクセス可能であれば、両方のマシンでこれを実行してください。私はロックなどをチェックすると、この問題のいくつかの回避策を試しましたが、私が解決できる唯一の方法はこれを無効にすることでした。この問題は、実際にはロックされているのではなく、ファイル共有プロトコルのより低いレベルのもので起こっています。

See this article for more detail

+0

ファイルが存在する場合(存在を確認するためにコードを変更する必要があります)、合理的なサイズであるため、これはおそらく私の問題ではありません。接続時にハングアップするようです。たぶんExistsは接続の問題を暴露し、うまくタイムアウトするでしょう。 – rheitzman

+0

私が問題を抱えたとき、それは大きなファイルか小さなファイルかは関係ありませんでした。 .netアプリを30種類のマシンにプッシュするスクリプトを使用していました。断続的に、これらのマシンのいくつかは、再起動が完了するまで、ファイル共有のロックアップを持ちます。上記の方法で修正しました。 – FloatingKiwi

+0

私は実際にターゲットマシンにアクセスしていないので、より汎用的なソリューションが必要です。 – rheitzman

関連する問題