1

I've seen other similar questions here but I can't seem to find a solution for my specific problem.

I'm writing a Twitch Bot and need to update a listbox on the main form when a message is received from the server. I made a custom event in my TwitchBot.cs class called OnReceive that looks like this:

public delegate void Receive(string message);
public event Receive OnReceive;

private void TwitchBot_OnReceive(string message)
{
    string[] messageParts = message.Split(' ');
    if (messageParts[0] == "PING")
    {
        // writer is a StreamWriter object
        writer.WriteLine("PONG {0}", messageParts[1]);
    }
}

The event is raised in the Listen() method of my TwitchBot class:

private void Listen()
{
    //IRCConnection is a TcpClient object
    while (IRCConnection.Connected)
    {
        // reader is a StreamReader object.
        string message = reader.ReadLine();

        if (OnReceive != null)
        {
            OnReceive(message);
        }
    }
}

When connecting to the IRC back-end, I call the Listen() method from a new thread:

Thread thread = new Thread(new ThreadStart(Listen));
thread.Start();

I then subscribed to the OnReceive event in the main form using the following line:

// bot is an instance of my TwitchBot class
bot.OnReceive += new TwitchBot.Receive(UpdateChat);

Finally, UpdateChat() is a method in the main form used to update a listbox on it:

private void UpdateChat(string message)
{
    lstChat.Items.Insert(lstChat.Items.Count, message);
    lstChat.SelectedIndex = lstChat.Items.Count - 1;
    lstChat.Refresh();
}

When I connect to the server and the Listen() method runs, I get an InvalidOperationException that says "Additional information: Cross-thread operation not valid: Control 'lstChat' accessed from a thread other than the thread it was created on."

I've looked up how to update UI from a different thread but can only find things for WPF and I'm using winforms.

Lews Therin
  • 3,707
  • 2
  • 27
  • 53
  • 1
    possible duplicate of [Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on](http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the) – Craig W. Jul 20 '15 at 17:41
  • I've looked at that link and still don't have a solution for this. Could you please explain what I'm looking for in that link/how it relates to my problem? I don't understand how to specifically use the [System.Windows.Forms.Control.Invoke](https://msdn.microsoft.com/en-us/library/System.Windows.Forms.Control.Invoke.aspx) it references in that link with the code I posted in the question. – Lews Therin Jul 20 '15 at 17:54

1 Answers1

1

You should check the Invoke for UI thread

private void UpdateChat(string message)
{
    if(this.InvokeRequired)
    {
        this.Invoke(new MethodInvoker(delegate {
            lstChat.Items.Insert(lstChat.Items.Count, message);
            lstChat.SelectedIndex = lstChat.Items.Count - 1;
            lstCat.Refresh();
        }));           
    } else {
            lstChat.Items.Insert(lstChat.Items.Count, message);
            lstChat.SelectedIndex = lstChat.Items.Count - 1;
            lstCat.Refresh();
    }
}
Community
  • 1
  • 1
Nikson Kanti Paul
  • 3,394
  • 1
  • 35
  • 51
  • Awesome! This is exactly what I needed. Thanks for linking that informative write-up and for showing me how to use invoke. This works great now! – Lews Therin Jul 20 '15 at 21:49