あなたがやろうとしていることは簡単ではありません。Console.WriteLine()
他static
は共有されているためです。これらのメソッドを呼び出すスレッドは、標準出力ストリームに書き込みます。
出力を個別のファイルに分割する最もクリーンな方法は、TextWriter
複数の出力ファイルをラップする独自のファイルを作成し、それを標準出力として設定することです。TextWriter
次に、必要な出力ファイルを指定して、各スレッド自体を に登録します。呼び出しがライターに着信するたびに、どのスレッドが呼び出しを行ったかを確認し、適切なファイルに書き込みます。
これを正しく行うには明らかにいくつかの作業が必要ですが (多数の競合状態やリソース共有の問題が発生する可能性があるため)、やりたいことができるようになります。
編集:これは、そのようなライターがどのように見えるか、およびそれがどのように使用されるかのサンプルです。このクラスは不完全で (たとえば、現在は s のみをサポートしていますWriteLine()
) string
、他のバグも存在する可能性があります。
public class ThreadAwareStreamWriter : TextWriter
{
private ConcurrentDictionary<int, TextWriter> threadWriterMap;
private TextWriter defaultWriter;
public ThreadAwareStreamWriter()
{
this.threadWriterMap = new ConcurrentDictionary<int, TextWriter>();
this.defaultWriter = Console.Out;
}
public TextWriter RegisterThreadWriter(TextWriter threadWriter)
{
int threadId = Thread.CurrentThread.ManagedThreadId;
TextWriter oldWriter;
this.threadWriterMap.TryGetValue(threadId, out oldWriter);
this.threadWriterMap[threadId] = threadWriter;
return oldWriter;
}
public void DeregisterThread()
{
TextWriter threadWriter;
if (this.threadWriterMap.TryRemove(Thread.CurrentThread.ManagedThreadId, out threadWriter))
{
threadWriter.Close();
}
}
public override Encoding Encoding
{
get
{
TextWriter threadWriter;
if (this.threadWriterMap.TryGetValue(Thread.CurrentThread.ManagedThreadId, out threadWriter))
{
return threadWriter.Encoding;
}
return this.defaultWriter.Encoding;
}
}
public override void WriteLine(string value)
{
TextWriter threadWriter;
if (this.threadWriterMap.TryGetValue(Thread.CurrentThread.ManagedThreadId, out threadWriter))
{
threadWriter.WriteLine(value);
return;
}
if (this.defaultWriter != null)
{
this.defaultWriter.WriteLine(value);
}
}
}
サンプルプログラム:
public static void Main(string[] args)
{
ThreadAwareStreamWriter writer = new ThreadAwareStreamWriter();
Console.SetOut(writer);
Thread t = new Thread(o =>
{
ThreadAwareStreamWriter tWriter = (ThreadAwareStreamWriter)o;
tWriter.RegisterThreadWriter(new StreamWriter(File.Open("test.txt", FileMode.Create, FileAccess.ReadWrite)));
Console.WriteLine("Hello from another thread");
tWriter.DeregisterThread();
});
t.Start(writer);
Console.WriteLine("Hello");
Console.ReadLine();
}
これにより、「Hello」がコンソールに出力され、「Hello from another thread」がファイル「test.txt」に出力されます。