0

背景: ログ ファイル (.txt) に書き込む必要があるいくつかの異なるスレッドがあります。スレッド間でこのファイルを共有する方法が必要ですが、これを行う方法がわかりません。おそらくある種のキューを使用し、このキューをポーリングしてメッセージをテキストファイルなどにプッシュすることを読みました. または、ファイルをロックして、前のメッセージが終了した後にキュー内のメッセージを書き込む必要がありますか?

現在、私はそのように書いています。

  fileToWrite = new System.IO.StreamWriter(DeviceManager.logPath + correctDateTimeFormat);

しかし、エラーメッセージが表示されます。

 The process cannot access the file 'filename' because it is being used by another process.

複数のスレッドが同時にこれにアクセスしようとしているとしか思えません。

これでどのようなアプローチをとるべきかについて、誰かが私を正しい方向に向けることができますか?

4

2 に答える 2

2

これらはあなたがここで直面している2つの異なる問題です。

  1. ファイルを閉じる前に、ファイルを再度開く-これは、適切な共有フラグを使用して開くことで実行できます
  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
    }
}

繰り返しになりますが、ここで達成しようとしていることの基本的なルールを示すだけで、非常に簡単です。

ここにある他のいくつかのオプション:

  1. すぐに使用できるログライブラリを使用する(Log4NetまたはNLog(私は個人的に好む))
  2. ログはキューにメッセージを追加する場合があり、ロガーがこのキューからメッセージを読み取って書き込むための内部の別のスレッドを持つことができます。これにより、ロガーの呼び出し元はログメッセージがログを完了するのを待つ必要がなくなります。
于 2012-06-29T13:13:55.503 に答える
1

wpf http://codetechnics.blogspot.com/2010/09/how-to-configure-initialize-and-using.htmlで log4net をどのように使用するかについては、この投稿を参照して ください 。 ' が見つかりませんでした (using ディレクティブまたはアセンブリ参照がありませんか?)

log4net は、クライアント プロファイルに含まれていないsystem.web.dllにアクセスする必要があるようです。

プロジェクトのプロパティ ページを開き、ターゲット フレームワーク.Net Framework 4に設定して、変更を保存します。

于 2012-06-29T13:37:13.827 に答える