|
-
Aug 31st, 2005, 04:02 AM
#1
Thread Starter
Frenzied Member
How does one thread speak to the main thread
Hi there,
I have a thread running a sub, and in the sub, i want it to change the controls on the main thread, How can i get the new thread to communicate with the main thread?
CHeers!
If you find my thread helpful, please remember to rate me 
-
Aug 31st, 2005, 04:55 AM
#2
Thread Starter
Frenzied Member
Re: How does one thread speak to the main thread
I basically want to stop my program crashing due to accessing a function on a dll file...
any ideaS?
If you find my thread helpful, please remember to rate me 
-
Aug 31st, 2005, 08:17 AM
#3
Re: How does one thread speak to the main thread
Read the article on Thread Synchronization http://www.devcity.net/Articles/160/2/article.aspx
Regards
Jorge
"The dark side clouds everything. Impossible to see the future is."
-
Aug 31st, 2005, 02:36 PM
#4
Fanatic Member
Re: How does one thread speak to the main thread
(I hope this helps if that link that Asgorath posted is a bit daunting. I looked at it quickly and it seemed to have a lot more information than I think you're looking for. A quick scan didn't mention anything about delegates either.)
To access a control that isn't on the thread that's running, you need to use a delegate.
I'm not a pro at delegates or multithreading, but I've taught myself how to use them, and it seems to work.
Basically, you have to put all your code that you are using to manipulate the control in its own sub. Now, calling this normally out of your thread will still produce an error, as the sub is still called from within the thread. You need to also create a delegate to call the thread up.
Let's say you wanted to update a status of a label from within your thread. First of all we'll need to call the sub that is going to update the status. Here's an example of what the sub could be like:
VB Code:
Private Sub UpdateLabel(ByVal strText As String)
Label.Text = strText
End Sub
Of course that's not going to work because we don't have any delegate stuff in there, but it's to illustrate the arguments we'll need to pass, which is just one, being strText.
So we can make a delegate to go with this sub. The delegate must have the same parameters that the sub it's going to call has.
VB Code:
Private Delegate Sub UpdateLabelDelegate(ByVal strText As String)
Simply write this onto a line like any other declaration outside of a sub or function. We can now call this from within the UpdateLabel sub.
Here's the new sub, with the delegate stuff in! (I'll explain after):
VB Code:
Private Sub UpdateLabel(ByVal strText As String)
If Label.InvokeRequired Then
Dim d As New UpdateLabelDelegate(AddressOf UpdateLabel)
Label.Invoke(d, strText)
Else
Label.Text = strText
End If
End Sub
Hope that's not too daunting! I'll just explain what's going on.
We're checking to see if an invoke is required. This will be True if the Label is trying to be accessed from within a thread it's not on. So if it is true, we go and Dim a new UpdateLabelDelegate for us to let the label invoke to. We have this delegate to the AddressOf the UpdateLabel sub (so it basically loops back through to do the sub again).
On the next line we get the label to invoke to the delegate, as you can see. Invoke takes two arguments, one being the delegate to invoke to, and the second being the arguments you're passing (in this case the strText).
Now it's going to do this thread again, except not on the thread you originally called it from (thanks to the delegate). So this time InvokeRequired is false because it's gone through the delegate. The delegate has passed the strText into the UpdateLabel argument, so don't worry - you haven't lost the text.
It'll skip to the Else block and just update the label with the text that was originally passed.
So that's it basically! The good thing about this is that you can call this sub from wherever and it'll act no differently wherever you call it from within a thread or outside of one. If you call it outside of one, it'll just skip to the else statement and not bother with delegates because it won't need them.
I hope this has helped! If it hasn't (maybe I've given you something totally irrelevant and I've misunderstood you), hopefully someone else will find it useful.
Good luck!
(I haven't tested any of this, as I haven't written any of it in the IDE, so I hope there's no errors)
-
Aug 31st, 2005, 02:44 PM
#5
Fanatic Member
Re: How does one thread speak to the main thread
Just had a thought that you may need to know in the future! If you're trying to pass several arguments to the delegate, pass them as an array.
Example: If you had a second argument for another label (let's say strText2) then you'll need to put both strText and strText into an array.
VB Code:
Dim args() as String = {strText, strText2} 'Declare the array and pass in the texts.
Label.Invoke(d, args) 'Invoke the delegate with the array instead of a single string
If you've got several different data types you're trying to pass, declare the args as an object instead. Example: You're trying to pass some text, but update differently if a boolean is true or not.
VB Code:
Dim args() as Object = {strText, bolBoolean}
Remember to keep the order of things. Don't try passing the boolean before the text if it's not before it in the paremeters.
-
Jan 18th, 2006, 09:30 PM
#6
Lively Member
Re: How does one thread speak to the main thread
Just wanted to say that this is an excellent thread.
One change I needed to make...
VB Code:
Private Sub UpdateLabel(ByVal strText As String)
If Label.InvokeRequired Then
Dim d As New UpdateLabelDelegate(AddressOf UpdateLabel)
Label.Invoke(d, strText)
Else
Label.Text = strText
End If
End Sub
became....
VB Code:
Private Sub UpdateLabel(ByVal strText As String)
If Label.InvokeRequired Then
Dim d As New UpdateLabelDelegate(AddressOf UpdateLabel)
Invoke(d, strText)
Else
Label.Text = strText
End If
End Sub
-
Oct 26th, 2006, 01:59 PM
#7
Lively Member
Re: How does one thread speak to the main thread
Lithia and Thrain,
Pun intended, this thread is awesome.
In my case, I have a custom chat program that uses sockets. Works fine in VS 2003 (or, more accurately, VS 2003 doesn't flag that particular bad programming practice), but I was getting cross-thread errors in after my port of the chat client to VS 2005 when the chat server called a chat client to deliver a chat message. And, I'm presuming that when I port my chat server to VS 2005, I'm going to have to fix the same problem there.
This approach did the trick, and did it simply.
Thanks much!
Bill
If you like my posts, please rate them so I can be somebody!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|