[英]Console.Error and Console.Out not writing on Redirected File Streams
[英]Two thread - two streams for Console.out
所有
我有一个图书馆,而不是我的图书馆,因此它无法修改。 这个库有两个方法,我们称之为Method_1()和Method_2()。 在这些方法中称为Console.WriteLine(“...”)
我上了课
public class CustomBackgroundWorker: BackgroundWorker
{
private readonly StringBuilder logBuilder;
public CustomBackgroundWorker ()
{
logBuilder = new StringBuilder ();
TextWriter outStream = new StringWriter (logBuilder);
Console.SetOut (outStream);
}
public string GetLogs ()
{
return logBuilder.ToString ();
}
}
它创建了这个类的两个实例。 每个实例都从库中执行方法。 但是输出只保存在一个流中,因为SetOut()方法全局工作。 是否可以将不同线程的输出重定向到单独的流?
谢谢
你要做的事情并不容易。 Console.WriteLine()
等是static
因为它们是共享的; 调用这些方法的任何线程将写入到标准输出流。
将输出拆分为单独文件的最简洁方法是创建自己的TextWriter
,它包装多个输出文件,并将其设置为标准输出。 然后,让每个线程使用TextWriter
注册自己,指定所需的输出文件。 每当调用进入编写器时,它会查看哪个线程进行了调用,然后写入相应的文件。
这显然需要做一些工作才能做好(因为有许多种族条件和资源共享问题可能会出现这种情况)但是可以让你做你想做的事情。
编辑 :这是一个这样的作家可能看起来的样本,以及如何使用它。 这个类是不完整的(例如,它目前只支持string
s的WriteLine()
),并且可能还存在其他错误。
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”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.