简体   繁体   English

C#Console.SetOut跨线程操作无效

[英]C# Console.SetOut Cross-thread operation not valid

I have a console application and I want to make a GUI for it now I want to send the console text to a textbox I know this is asked more but I can't get it to work :S :S 我有一个控制台应用程序,我想为它制作一个GUI现在我想将控制台文本发送到文本框我知道这个问题更多,但我无法让它工作:S:S

I used this code in my Form1 Load : 我在Form1 Load中使用了这段代码:

private void Form1_Load(object sender, EventArgs e)
{
    Console.SetOut(new TextBoxWriter(consoleTextbox));
}

and this is the TextBoxWriter class : 这是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; }
        }
    }
}

But when I start my program and start my server system it returns this error : 但是,当我启动我的程序并启动我的服务器系统时,它返回此错误:

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll System.Windows.Forms.dll中发生了未处理的“System.InvalidOperationException”类型异常

Additional information: Cross-thread operation not valid: Control 'consoleTextbox' accessed from a thread other than the thread it was created on. 附加信息:跨线程操作无效:控制'consoleTextbox'从其创建的线程以外的线程访问。

Controls cannot be changed by Threads other than the UI Thread. UI线程以外的线程无法更改控件。 Your Console is running its own Thread.. and it is calling into your class and attempting to change the Textboxes text. 您的控制台正在运行自己的Thread ..它正在调用您的类并尝试更改Textboxes文本。

To stop this, you need to make sure that the text change operation takes place on the UI thread. 要停止此操作,您需要确保在UI线程上进行文本更改操作。 You can do this by using say, Invoke : 您可以使用say, Invoke来执行此操作:

_output.Invoke(new MethodInvoker(() => _output.AppendText(value.ToString())));

Windows forms UI controls can only be accessed from the UI thread. Windows窗体UI控件只能从UI线程访问。 You can use the Invoke() method on a control to queue up an action to run on said thread. 您可以在控件上使用Invoke()方法来排队要在所述线程上运行的操作。 For example, you could change your implementation of Write() to be: 例如,您可以将Write()的实现更改为:

    public override void Write(char value)
    {
        var text = value.ToString();
        this._output.Invoke(new Action(() => this._output.AppendText(text)));
    }

As the error is trying to tell you, you cannot interact with the UI from a non-UI-thread. 由于错误试图告诉您,您无法从非UI线程与UI进行交互。

A background thread is trying to write to the console, making your stream interact with the textbox from the wrong thread. 后台线程正在尝试写入控制台,使您的流与错误线程中的文本框进行交互。

Instead, you should call the BeginInvoke() method in Write() to asynchronously run your code on the UI thread. 相反,您应该在Write()调用BeginInvoke()方法,以在UI线程上异步运行代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM