2

さて、私のプログラムには約 30 のスレッドがあり、各スレッドを通じて収集された情報の一部をログに記録する必要があります。

私がこれを行った方法は次のとおりです。 クラス Program で public static StringBuilder を作成すると、各スレッドが数分ごとにこの StringBuilder インスタンスに AppendLine メソッドを呼び出します。次に、30 分ごとに、StreamWriter を使用した書き込み専用の別のスレッドがまさにそれを行います。

例えば:

public class Program
{
    public static StringBuilder sb  = new StringBuilder();
    public static void Main(string[] args)
    {
        // Start all threads
    }
}

public class Example
{
    Thread t1 = new Thread(() =>
    {
        while(true)
        {
            DoSomething();
        }
    });

    Thread logThread = new Thread(() =>
    {
        while(true)
        {
            using(StreamWriter writer = new StreamWriter(Path))
            {
                writer.Write(Program.sb);
            }
        }
    });

    public static void DoSomething()
    {
        // Will do something for a few minutes.
        Program.sb.AppendLine("Some text gathered before...different everytime!");
    }
}

これはこれを行う良い方法ですか?

ありがとう

4

4 に答える 4

3

いいえ、StringBuilderスレッド セーフではないため、複数のスレッドで同時に使用すると破損する可能性があります。

キーワードStringBuilderを使用してへのアクセスを同期します。lockプライベートにして、安全に操作するためのパブリック メソッドを提供します。

private static StringBuilder _sb = new StringBuilder();
private static object _sbSync = new Object();

public static void AppendLine(string line) {
  lock (_sbSync) {
    _sb.appendLine(line);
  }
}

public static string GetLines() {
  lock (_sbSync) {
    string result = _sb.ToString();
    _sb = new StringBuilder();
    return result;
  }
}
于 2013-09-21T13:03:26.797 に答える
3

ReaderWriterLockSlim を使用できますhttp://www.johandorper.com/log/thread-safe-file-writing-csharp

private static ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim();

public void WriteToFile(string text, string path) 
{
    _readWriteLock.EnterWriteLock();
    using (StreamWriter sw = new StreamWriter(path, true))
    {
        sw.WriteLine(text);
        sw.Close();
    }
    _readWriteLock.ExitWriteLock();
}
于 2014-11-10T05:04:42.093 に答える