1

我有一个控制台应用程序,现在我想为它制作一个 GUI 我想将控制台文本发送到一个文本框我知道这被问到了更多但我无法让它工作:S:S

我在 Form1 Load 中使用了这段代码:

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.dll 中出现“System.InvalidOperationException”类型的未处理异常

附加信息:跨线程操作无效:控件“consoleTextbox”从创建它的线程以外的线程访问。

4

3 回答 3

3

控件不能由 UI 线程以外的线程更改。您的控制台正在运行自己的线程。它正在调用您的类并尝试更改文本框文本。

要阻止这种情况,您需要确保文本更改操作发生在 UI 线程上。你可以通过使用 say, 来做到这一点Invoke

_output.Invoke(new MethodInvoker(() => _output.AppendText(value.ToString())));
于 2013-10-14T21:55:28.947 回答
0

Windows 窗体 UI 控件只能从 UI 线程访问。您可以在控件上使用 Invoke() 方法来排队要在所述线程上运行的操作。例如,您可以将 Write() 的实现更改为:

    public override void Write(char value)
    {
        var text = value.ToString();
        this._output.Invoke(new Action(() => this._output.AppendText(text)));
    }
于 2013-10-14T21:53:41.153 回答
0

正如错误试图告诉您的那样,您无法从非 UI 线程与 UI 交互。

后台线程正在尝试写入控制台,使您的流与来自错误线程的文本框交互。

相反,您应该调用该BeginInvoke()方法Write()以在 UI 线程上异步运行您的代码。

于 2013-10-14T21:54:06.343 回答