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

エラーが伝えようとしているように、非 UI スレッドから UI を操作することはできません。

バックグラウンド スレッドがコンソールへの書き込みを試みているため、ストリームが間違ったスレッドからのテキスト ボックスとやり取りしています。

BeginInvoke()代わりに、メソッドを呼び出してWrite()、UI スレッドでコードを非同期に実行する必要があります。

于 2013-10-14T21:54:06.343 に答える
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 に答える