これらはあなたがここで直面している2つの異なる問題です。
- ファイルを閉じる前に、ファイルを再度開く-これは、適切な共有フラグを使用して開くことで実行できます
- それへのアクセスを同期します。これは、一度に1つのスレッドのみがファイルにアクセスできるようにするミューテックスを使用することで実行できます。これは重要です。そうしないと、スレッドが同時にファイルに書き込む可能性があり、メッセージが自分自身の間で交差するなどの問題が発生する可能性があります。
このパラメーター付きのFileStreamコンストラクターFileSharing
は、ファイルを閉じる前に、いくつかのスレッドからファイルを開くのに役立ちます。
ただし、必要に応じて、ファイル(ログファイルなど)へのアクセスを1か所に集中させ(この特定のファイルへのアクセスを制御するインスタンスを1つ持つクラスを作成する)、次のことを確認することをお勧めします。いくつかのプライベートミューテックスをロックすることで異なるスレッドからのアクセスを同期するため、同時にいくつかのスレッドからファイルに書き込むことはありません。
非常に単純な例で、構築する必要があります。
class Logger : IDisposable
{
private FileStream file; //Only this instance have a right to own it
private StreamWriter writer;
private object mutex; //Mutex for synchronizing
public Logger(string logPath)
{
file = new FileStream(logPath);
writer = new StreamWriter(file);
mutex = new object();
}
// Log is thread safe, it can be called from many threads
public void Log(string message)
{
lock (mutex)
{
writer.WriteLine(message);
}
}
public void Dispose()
{
writer.Dispose(); //Will close underlying stream
}
}
繰り返しになりますが、ここで達成しようとしていることの基本的なルールを示すだけで、非常に簡単です。
ここにある他のいくつかのオプション:
- すぐに使用できるログライブラリを使用する(Log4NetまたはNLog(私は個人的に好む))
- ログはキューにメッセージを追加する場合があり、ロガーがこのキューからメッセージを読み取って書き込むための内部の別のスレッドを持つことができます。これにより、ロガーの呼び出し元はログメッセージがログを完了するのを待つ必要がなくなります。