Designing with Threads

Started by
3 comments, last by Shashwat Rohilla 12 years, 8 months ago
I'm using C#.Net in VS 2008.

I'm creating a Chat Messenger using form application.
A server is running and different users log in as clients and chat.

On the client side, two thread are running.
One is the main thread to display everything and call the event handlers.
The other one is for receiving the data from the server and take appropriate actions.
To take action, this thread parse the data received by the server (by calling another function), processes it.
Now, in the main Thread, I've created a listbox which stores the contacts received from the server.
But this is being updated from the second Thread.

It is running fine.
But while debugging, it gives a CrossThreadOperationException whenever it updates this listbox. It says that this listbox was not created in the Thread in which it is being used.

Tell me whether it is a good design to do so.
So many cross thread operations like that would be there.

Is it possible to share a string value between these two threads?
Whenever the second one updates the value of the string, some method is triggered from the first thread to parse and process it?
Advertisement
Given that your data is relative simple (a string), probably fairly low bandwidth and your target thread is already a UI thread, why not pass the data between the threads using a message?

In the server you could just new a string class, put your data in it. Post a custom designed message to the UI thread containing a pointer to the string class. The UI thread will get the message in the usual message loop and then just either appends it to the listbox and or copies it in/deletes the string class (don't how your listbox class does this).

It's nice and scalable, doesn't involve any scary thread communication and fits really nicely with your application structure.
While I was working with WinForms I usually did something along these lines, pseudo-C#:

void addToLog(string text) {
if(InvokeNeeded())
BeginInvoke(addToLog_threadSafe, text);
else
addToLog(text);
}

void addToLog_threadSafe(string text) {
mLogControl.add(text);
}


I'm not expert so this might be horribly inefficient performance-wise on top of requiring you to write two functions for everything but it worked well enough for me.
[size="1"]trassel (thread lib)
You need to call InvokeRequired() on the control in question. For example, label1.InvokeRequired() and if true you fire off a delegate call with the same control's .Invoke(delegate) method. If the control has a BeginInvoke you can use that as well. You just need to choose if you want an asynchronous call or not.

You need to call InvokeRequired() on the control in question. For example, label1.InvokeRequired() and if true you fire off a delegate call with the same control's .Invoke(delegate) method. If the control has a BeginInvoke you can use that as well. You just need to choose if you want an asynchronous call or not.

Already did that.. Now its working fine...
We can not create or update a UI component in a thread other than main thread.
Thanks for telling..

This topic is closed to new replies.

Advertisement