ASP.NETでテキストファイルを開く/書き込む際に問題が発生する
-
11-07-2019 - |
質問
人がページを読み込むたびに、テキストファイルにいくつかの統計情報を書き込みたいです。しかし、たまに「Could Not Open File、Already in use」タイプのエラーが発生します。このエラーを100%再現することはできません。非常に不安定です。私のコードは
ですPublic Sub WriteStats(ByVal ad_id As Integer)
Dim ad_date As String = Now.Year & Now.Month
Dim FILENAME As String = Server.MapPath("text/BoxedAds.txt")
Dim objStreamWriter As StreamWriter
objStreamWriter = File.AppendText(FILENAME)
objStreamWriter.WriteLine(ad_id & ";" & ad_date)
objStreamWriter.Close()
End Sub
私の質問は、エラーを取得しないようにファイルをロックおよびロック解除するにはどうすればよいですか?
ありがとう
解決
例外を処理し、短いランダムな間隔の後にファイルへの書き込みを再試行するための処理を構築する必要があります。
競合が多すぎる場合は、データベース内のテーブルにログを記録し、ファイルにエクスポートするプロセスを作成する方が賢明かもしれません(まだ必要な場合)
他のヒント
2つ以上のリクエストがWebサーバーにほぼ同時にヒットした場合、それらはすべて同じファイルを開こうとします。リクエストごとに一意のファイル名を作成する必要があります。
Public Sub WriteStats(ByVal ad_id As Integer)
Dim ad_date As String = Now.Year & Now.Month
Dim FILENAME As String = Server.MapPath("text/BoxedAds.txt")
Dim index As Integer
Using fs As New IO.FileStream(FILENAME, IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.ReadWrite), _
tl As New TextWriterTraceListener(fs)
index = Trace.Listeners.Add(tl)
Trace.WriteLine(ad_id & ";" & ad_date)
Trace.Listeners(index).Flush()
Trace.Flush()
End Using
Trace.Listeners.RemoveAt(index)
End Sub
ここで3つの重要なこと:
- IO.FileShare.ReadWriteを使用して、ファイルに対して複数のライターを一度に許可します。
- Usingステートメントは、例外が発生した場合でもストリームがすぐに閉じられるようにします。これにより、衝突が最小限に抑えられます
- TextWriterTraceListenerは、メッセージが失われないようにするために、要求したファイルを開けない場合に、一時ファイルを作成します。
以下を使用して短い情報で問題が発生したことはありません。 File.AppendAllText(path、info);
ロックの原因となるコメントについては、リフレクターからは、Joelが非常によく説明している同じオプションを使用します。トレースライターを使用しないため、高負荷/大容量のコンテンツがトラブルを引き起こす場合、一時ファイルに出力されません。
情報が大きい場合は、個別のファイルが必要です。高負荷の場合、Joelの提案に従って一時ファイルを作成します。これは、File.AppendAllTextで例外をキャッチし、同じFile.AppeandAllTextを一意のファイル名で使用することによっても実行できます。