Question

I'm having this issue. I need to be able to append the incoming messages to txtConsole from within OnMessage, but I'm getting an Illegal Cross Thread error. How do I get around this? I'm pretty basic when it comes to C# so some code (no psuedocode) with explanations would be helpful please.

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);
        }
    }
}
Était-ce utile?

La solution

The reason you're getting that error is because you're trying to update a UI element from a non-UI thread. You can call the control's Invoke method to force it to run on the UI thread.

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);
    }
}

Autres conseils

That exception appears when you try to access other thread (for example, UI Thread), from another different thread.

You can solve that calling

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

from any thread you want

How to Properly Handle Cross-thread Events and Update a Label with BeginInvoke and BackgroundWorker

Cross Thread UI control access

Just replace txtConsole.AppendText in method OnMessage with

txtConsole.Invoke((Action)(() => txtConsole.AppendText(Environment.NewLine + msg.Text)));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top