Community discussion forum

How to work around Cross-thread operation not valid with threading [C#/CS 2005]

  • 3 years ago

    I am creating a CHAT interface for my game (when networking, server/client style) and I ran into a little problem...

    The way it works... I have forms for the SERVER (frmServer) and CLIENTS (frmClient) each of them have a LISTBOX (lbChat) in which I input (lbChat.Items.Add(string)) text as the users type it - in essence a chatbox...

    So, let's use the CLIENT as an example (as it is simpler and the concept the same in both client and server cases)...
    The Client form (frmClient) creates a thread that is used to listen for chat messages (via TCP) - so what I did was pass the listbox itself (lbChat) to the thread thus (I thought) solving my problem of writing into the listbox when chat messages arrive (and are caught by the thread and not frmClient of course)...
    Now while debugging the code I get the following exception when my thread attempts to write in the listbox (lbChat) of frmClient
    General Exception: System.InvalidOperationException: Cross-thread operation not valid: Control 'lbChat' accessed from a thread other than the thread it was created on.


    So now the question is how do I work around this cross-thread exception? How do I pass information (chat text) from my listener threads (and there will be multiple of them in the field, one per client) to the centralized listbox (lbChat) on the form?
    I need some kind of method to transfer information while also reducing the chances of running into contention issues (do I need to use ReaderWriterLock?), thing is I have no clue how to accomplish this task (I thought simply passing in the listbox would allow me to write to it in each of the threads)...

    Any ideas, hints, and help would be greatly appreciated, thanks

  • 3 years ago
    You have two choices.  You can use a BackgroundWorker instead of explicitly creating a Thread, then call its ReportProgress method, which raises the ProgressChanged event in the UI thread.  Alternatively you can employ delegation to cross the thread boundary.  Here's an example of using a delegate to add an item to a ListBox:
    private delegate void AddListBoxItemDelegate(object item);

    private void AddListBoxItem(object item)
    {
    if (this.listBox1.InvokeRequired)
    {
    // This is a worker thread so delegate the task.
    this.listBox1.Invoke(new AddListBoxItemDelegate(this.AddListBoxItem), item);
    }
    else
    {
    // This is the UI thread so perform the task.
    this.listBox1.Items.Add(item);
    }
    }















    Now you can simply call the AddListBoxItem method from anywhere and it will handle the delegation itself if required.

  • 8 months ago
    3 years now and still needed !!! tks to you John. I tried events called by the thread (because i need it from an external class)...doesn't work of course :-) But with you example, never mind the way you want to solve trouble shooting Cross-thread, the penny dropped. So far to go and so many things to know nice trip to you by

Post a reply

Enter your message below

Sign in or Join us (it's free).

We'd love to hear what you think! Submit ideas or give us feedback