C# Console.WriteLine() 在设置 Console.SetOut() 后不能在其他线程中工作?
C# Console.WriteLine() not working in other thread after setting Console.SetOut()?
我正在开发一个 Windows 表单应用程序,在我的表单中,我创建了一个跨线程安全的 TextWriter class,我将其用于 Console.SetOut() 以显示在 RichTextBox 中写入控制台,如下所示:
public class TextboxWriter : TextWriter
{
private RichTextBox box;
public TextboxWriter(RichTextBox b)
{
box = b;
}
public override Encoding Encoding => Encoding.ASCII;
public override void Write(string value)
{
Debug.WriteLine(value);
box.Invoke((MethodInvoker)delegate ()
{
box.Text += "[" + DateTime.Now.ToString("HH:mm:ss") + "] " + value + "\n";
});
}
}
Console.SetOut() 在创建和加载 DiscordConsole class 时被调用, 这在我调用 Console.WriteLine( ) 在 STAThread 或任何其他线程中,例如:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
DiscordConsole f = new DiscordConsole();
Thread t = new Thread(Separate);
t.Start();
Application.Run(f);
}
private static void Separate()
{
Thread.Sleep(1000);
Console.Write("Loading...");
// loading functions
Console.Write("Load complete!");
}
那些对 Console.WriteLine() 的调用工作正常。 但是,我的加载函数也创建了多个线程,但在这些线程中,对 Console.WriteLine() 的调用不会在 TextBox 上产生任何内容? 下面是我创建线程的方式并启动它们。
public static void LoadRegistry(bool downloadAgain)
{
List <Thread> threads = new List<Thread>();
string[] files = Directory.GetFiles(DataPath, "*.json");
float groupamountload = files.Length / (float)Groups;
for (int i = 0; i < Groups; i++)
{
int tmp = i;
Thread t = new Thread(() =>
{
Console.WriteLine("loading");
Debug.WriteLine("loading");
// loading code
});
threads.Add(t);
}
Application.ApplicationExit += delegate (object info, EventArgs e)
{
threads.ForEach(t => t.Abort());
};
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());
}
为了验证我的线程是 运行 并正在加载我的文件,我在线程中放置了 Debug.WriteLine() AND Console.WriteLine() 语句。我看到 Debug.WriteLine() 文本输出到 Visual Studio,但是 RichTextBox 没有用我的 Console.WriteLine() 更新。有谁知道我在这里做错了什么?
已解决
这个问题几乎没有引起注意,但我发现了它不起作用的原因。我的 TextboxWriter class 只会覆盖 Write() 函数,但不会覆盖 WriteLine() 函数。向 WriteLine(string) 添加覆盖使其工作!
我不确定为什么有些调用 Console.WriteLine() 会起作用,而有些则不会,但现在它们都起作用了。
我正在开发一个 Windows 表单应用程序,在我的表单中,我创建了一个跨线程安全的 TextWriter class,我将其用于 Console.SetOut() 以显示在 RichTextBox 中写入控制台,如下所示:
public class TextboxWriter : TextWriter
{
private RichTextBox box;
public TextboxWriter(RichTextBox b)
{
box = b;
}
public override Encoding Encoding => Encoding.ASCII;
public override void Write(string value)
{
Debug.WriteLine(value);
box.Invoke((MethodInvoker)delegate ()
{
box.Text += "[" + DateTime.Now.ToString("HH:mm:ss") + "] " + value + "\n";
});
}
}
Console.SetOut() 在创建和加载 DiscordConsole class 时被调用, 这在我调用 Console.WriteLine( ) 在 STAThread 或任何其他线程中,例如:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
DiscordConsole f = new DiscordConsole();
Thread t = new Thread(Separate);
t.Start();
Application.Run(f);
}
private static void Separate()
{
Thread.Sleep(1000);
Console.Write("Loading...");
// loading functions
Console.Write("Load complete!");
}
那些对 Console.WriteLine() 的调用工作正常。 但是,我的加载函数也创建了多个线程,但在这些线程中,对 Console.WriteLine() 的调用不会在 TextBox 上产生任何内容? 下面是我创建线程的方式并启动它们。
public static void LoadRegistry(bool downloadAgain)
{
List <Thread> threads = new List<Thread>();
string[] files = Directory.GetFiles(DataPath, "*.json");
float groupamountload = files.Length / (float)Groups;
for (int i = 0; i < Groups; i++)
{
int tmp = i;
Thread t = new Thread(() =>
{
Console.WriteLine("loading");
Debug.WriteLine("loading");
// loading code
});
threads.Add(t);
}
Application.ApplicationExit += delegate (object info, EventArgs e)
{
threads.ForEach(t => t.Abort());
};
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());
}
为了验证我的线程是 运行 并正在加载我的文件,我在线程中放置了 Debug.WriteLine() AND Console.WriteLine() 语句。我看到 Debug.WriteLine() 文本输出到 Visual Studio,但是 RichTextBox 没有用我的 Console.WriteLine() 更新。有谁知道我在这里做错了什么?
已解决
这个问题几乎没有引起注意,但我发现了它不起作用的原因。我的 TextboxWriter class 只会覆盖 Write() 函数,但不会覆盖 WriteLine() 函数。向 WriteLine(string) 添加覆盖使其工作!
我不确定为什么有些调用 Console.WriteLine() 会起作用,而有些则不会,但现在它们都起作用了。