C# Console.SetOut 跨线程操作无效
本文关键字:操作 无效 线程 Console SetOut | 更新日期: 2023-09-27 18:35:24
我有一个控制台应用程序,现在我想为它制作一个GUI,我想将控制台文本发送到文本框,我知道这被问得更多,但我无法让它工作:S :S
我在 Form1 加载中使用了这段代码:
private void Form1_Load(object sender, EventArgs e)
{
Console.SetOut(new TextBoxWriter(consoleTextbox));
}
这是 TextBoxWriter 类:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace KLFClient
{
public class TextBoxWriter : TextWriter
{
TextBox _output = null;
public TextBoxWriter(TextBox output)
{
_output = output;
}
public override void Write(char value)
{
base.Write(value);
_output.AppendText(value.ToString());
}
public override Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
}
但是当我启动程序并启动服务器系统时,它会返回此错误:
System.Windows.Forms 中发生了类型为"System.InvalidOperationException"的未处理异常.dll
其他信息:跨线程操作无效:从创建它的线程以外的线程访问的控件"consoleTextbox"。
控件不能由 UI 线程以外的线程更改。您的控制台正在运行自己的线程。它正在调用您的类并尝试更改文本框文本。
若要停止此操作,需要确保文本更改操作在 UI 线程上进行。你可以通过使用说,Invoke
来做到这一点:
_output.Invoke(new MethodInvoker(() => _output.AppendText(value.ToString())));
只能从 UI 线程访问 Windows 窗体 UI 控件。可以在控件上使用 Invoke() 方法将操作排队以在该线程上运行。例如,您可以将 Write() 的实现更改为:
public override void Write(char value)
{
var text = value.ToString();
this._output.Invoke(new Action(() => this._output.AppendText(text)));
}
正如错误试图告诉您的那样,您无法从非 UI 线程与 UI 交互。
后台线程正在尝试写入控制台,使您的流与来自错误线程的文本框交互。
相反,应在 Write()
中调用 BeginInvoke()
方法,以便在 UI 线程上异步运行代码。