1

私はこの問題を抱えています。OnMessage 内から受信メッセージを txtConsole に追加できるようにする必要がありますが、Illegal Cross Thread エラーが発生します。どうすればこれを回避できますか? 私は C# に関してはかなり基本的なので、説明付きのコード (疑似コードではない) が役立つでしょう。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Apache.NMS;
using Apache.NMS.Util;

namespace WindowsFormsApplication1
{
    public partial class frmConsole : Form
    {


        public frmConsole()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, System.EventArgs e)
        { }

        public void cmdConnect_Click(object sender, EventArgs e)
        {
            // Output to the user that the connection is being set up
            txtConsole.AppendText(Environment.NewLine + "Setting up connection...");
            // Define the feed URL
            IConnectionFactory factory = new NMSConnectionFactory(new Uri("stomp:tcp://datafeeds.networkrail.co.uk:61618"));
            // Define the credentials
            IConnection connection = factory.CreateConnection("REDACTED", "REDACTED");
            // Create the session
            ISession session = connection.CreateSession();
            // Specify which feed - we want TRAIN_MVT_ALL_TOC to listen for all train movements
            IDestination destination = session.GetDestination("topic://" + "TRAIN_MVT_ALL_TOC");
            // Let the end user know where we will be subscribing to
            txtConsole.AppendText(Environment.NewLine + "Will attempt subscription to " + destination);
            // Create a consumer for the feed
            IMessageConsumer consumer = session.CreateConsumer(destination);
            // Let the end user know we are about to connect...
            txtConsole.AppendText(Environment.NewLine + "Connecting...");
            // Connection details are now all set up. Start the connection...
            connection.Start();
            // Check we are connected
            if (connection.IsStarted == false)
            {
                txtConsole.AppendText(Environment.NewLine + "Connection closed.");
                connection.Close();
            }
            // Now we need to handle messages using a MessageListener where we pass it to the OnMessage void.
            consumer.Listener += new MessageListener(OnMessage);

            txtConsole.AppendText(Environment.NewLine + "Connection established. Waiting for messages...");


            // End of void
        }


        public void OnMessage(IMessage message)
        {

            ITextMessage msg = (ITextMessage)message;
            message.Acknowledge();
            txtConsole.AppendText(Environment.NewLine + msg.Text);
        }
    }
}
4

3 に答える 3

0

クロススレッド イベントを適切に処理し、BeginInvoke と BackgroundWorker でラベルを更新する方法

クロス スレッド UI コントロール アクセス

txtConsole.AppendTextメソッドOnMessageを次のように置き換えるだけです

txtConsole.Invoke((Action)(() => txtConsole.AppendText(Environment.NewLine + msg.Text)));
于 2013-04-01T17:39:22.507 に答える
0

このエラーが発生する理由は、非 UI スレッドから UI 要素を更新しようとしているためです。コントロールのInvokeメソッドを呼び出して、強制的に UI スレッドで実行することができます。

public void OnMessage(IMessage message)
{ 
    ITextMessage msg = (ITextMessage)message;
    message.Acknowledge();

    if (txtConsole.InvokeRequired)
    {
        txtConsole.Invoke(new Action(() =>
          {
             txtConsole.AppendText(Environment.NewLine + msg.Text);
          }));
    }
    else
    {
        txtConsole.AppendText(Environment.NewLine + msg.Text);
    }
}
于 2013-04-01T17:37:51.760 に答える
0

その例外は、別の別のスレッドから別のスレッド (UI スレッドなど) にアクセスしようとすると表示されます。

あなたはその呼び出しを解決することができます

Dispatcher.BeginInvoke(() => delegate{// Here the code});

好きなスレッドから

于 2013-04-01T17:38:57.077 に答える