Hi,
I'm developing on a new vb.net-application with the Visual Basic Express Edition.
Now I have to use a backgroundworker for a longer process. But I'd like to keep the user up-to-date, what the application is currently doing. So the Backgroundworker has to change some labels in the main Form.
Now the Question is: How to get the backgroundworker changing the label in another thread
I know, that I have to use invoke and delegate, but I don't know, how.
Can someone explain this to me
Thanks, Greetings from Germany and Regards,
Fabian

Multithreading and and "encroachments"
hrd2hndl67
Did you look at this one:
http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=839421&SiteID=1
it creates a second thread progmatically instead of using a background worker but should do the trick for you...
with the three links I provided it should give you enough information to get started...if you are still having problems...post the code and errors you are running into for better help!
Rainadaman
A delegate can point to a function as well as a subroutine. If you e.g. want to point to a function, which receives an integer and returns a string, you may define the delegate as:
Public Delegate Function NameOfDelegate(ByVal InputValue As Integer) As String ' Note Function instead of Sub
I don't know what happens if you use BeginInvoke (not Invoke) on a function. BeginInvoke returns immediately before the function is excecuted, so the return value is maybe not correct. The documentation only calls it IAsyncResult without any further description. With Invoke there should not be any problems since Invoke do not return before the function is finished so you should be able to use e.g.:
ReturnedString = GUIObject.Invoke(New NameOfDelegate(AddressOf YourFunction), IntegerInput)
I have not tried this so don't blame me if it does not work.
BeaverMan
micronax
Because the backgroundworker uses another thread than the GUI (General User Interface) you are not allowed to write directly to the label. Instead you must make a display routine - Display, which can do the job for you on the same thread as the GUI.
In VB.NET there are two ways to write in a thread safe way - Invoke and BeginInvoke. The difference is that Invoke do not return before the text is written (may take some time), but BeginInvoke returns immediately. Therefore, BeginInvoke is the most appropriate for jobs like this.
According to the help file in VB.NET, BeginInvoke executes a delegate asynchronously on the thread that the control's underlying handle was created on. It is hard to imagine a more cryptically explanation, but what the BeginInvoke method does is to execute a method (some code) on its own thread like any other subroutine call, but asynchronously. BeginInvoke has one or two arguments. The first one is the method to execute, and the second one is any argument(s) to transfer. All GUI objects plus the form classes inherit the BeginInvoke method from their common base class System.Windows.Forms.Control, so they all have this method.
In this case, you want to write something to a label - Label1 - in another thread, by means of Display. To avoid an illegal cross-thread call, the display routine must be executed on the same thread as Label1. Therefore you may use the BeginInvoke method of this label - Label1.BeginInvoke. This starts a method on the same thread as the label and returns immediately, but because the method (Display) is an object of another thread, you must use a delegate to point to this method. A delegate is an objects you can use to call the methods of other objects. It is sometimes described as a type-safe function pointer because it is similar to function pointers used in other programming languages like C.
In the declaration of the delegate it shall be specified whether the method is a function or a subroutine. If the display routine is a subroutine (it probably is), the delegate shall be declared as Public Delegate Sub .... It is also necessary to specify the argument(s) of the method to call. In this case the method (Display routine) has only one argument - the text string - TextString - to write. Because BeginInvoke returns immediately, it is necessary to transfer the string by value (ByVal) or else it may be overwritten before it is used. The total definition of the delegate therefore becomes Public Delegate Sub (NameOfDelegate(Byval Buffer As String). You have now declared a general useable delegate that may be used to transfer a string to a subroutine method of another object. You still need to define which method to receive the string. This is done in the BeginInvoke statement where you define a new instance of this delegate and point it to the display routine (AddressOf Display). What the whole statement Label1.BeginInvoke (New NameOfDelegate(AddressOf Display), TextString) does is therefore to invoke (start) the Display routine on the same thread as Label1, transfer the String as input and then return immediately (before the string is displayed).
Note that this description is a quick edit of a description from the knowledgebase on our homepage so if there is something I have forgotten to edit or there is still something you do not understand, ask again.
chongqing
a concret example
Public Delegate Function getPassword() As String
Function returnPassword()
Return LoginForm1.PasswordTextBox.Text
End Function
Dim password As String = Invoke(New getPassword(AddressOf returnPassword))
AND: IT WORKS!!
Thanks for your support
Dhivya.S
OK.. back to the topic:
I still dont check how to use this..
A Example:
Form1:
[statuslabel1]
[button_1] <-- Onclick: BackgroundWorker1.RunWorkerAsync()
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
do_something()
' And here I want to change the text of statuslabel1.. But how
End Sub
Thanks,
Micronax
IceAngel89
And how to change attributes of an object (like the style or a progressbar) in another thread
Thanks,
Micronax
Jawad Naeem
http://www.codeproject.com/useritems/mutithreading_for_beginer.asp
Michaelliu
Public Delegate Function NameOfDelegate(ByVal InputValue As Integer) As String ' Note Function instead of Sub
The NameOfDelegate is the "functionname"
John Belli
Are you shure, that this example contains a solution / way
Fabian
Michael Hansen
The same way! Display is not running on another thread!
All subroutines - event driven or not event driven - runs on the same thread as the one from which they are called, activated or invoked. Because you use the BeginInvoke method of StatusLabel1 it will run on the same thread as StatusLabel1. You could also have used Form1.BeginInvoke with the same result because StatusLabel1 uses the same thread as Form1 (GUI). It is important to understand that even though Display is defined in Form1 it will not automatically use that thread. It depends on from where it is called or invoked! Once a subroutine is running you can forget how it is invoked (BeginInvoke, Invoke, Call, "Handles xxx" etc.) and you can do the same things with this subroutine - changing attributes etc. - as long as it is running on the same thread. It is actually quite simple. Invoke works like any other call. This is also the case with BeginInvoke except that it returns immediately. Therefore the subroutine you call will use the same thread as the one from which it is called - in this case the same thread as StatusLabel1.
wpf michelle
Declare a delegate like this:
Public Delegate Sub StringSubPointer(Byval Buffer As String)
and make a display routine like this:
Private Sub Display(ByVal Buffer As String)
StatusLabel1.text = Buffer
End Sub
Then place the the following BeginInvoke statement just after the do_something() statements in your backgroundworker.
StatusLabel1.BeginInvoke(New StringSubPointer(AddressOf Display), TextStringYouWantToWrite).
This ought to work, but I have not tested it.
PS. Please use a bigger font the next time. Your last post is very difficult to read.
gg1
see the following walk-through example:
http://msdn2.microsoft.com/en-us/library/ms233672(vs.80).aspx
Give it a try and post back with any errors or specific problems you are having
Jutsin Leung
If that walkthough did not provide enough direction...please take alook at my solution in this thread:
http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=839421&SiteID=1
There is also a current multithread discussion going on here:
http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1087243&SiteID=1
StarsFire
Public Delegate Sub AttributeSubPointer(ByVal Buffer As String)
Sub changeType(ByVal Buffer As String)
If Buffer = "1" Then
start.ProgressBar1.Style = ProgressBarStyle.Continuous
Else
start.ProgressBar1.Style = ProgressBarStyle.Blocks
End If
End Sub
Ah.. end a (hopefully) last question :
Is there a possibility to define a delegate function with a return value (If not, how to get (for example) the value of textbox1 to my bgworker
(Sorry, normally I find out everything for myself (bad english ;)), but I didn't check everything of the declaration of delegate sub's or what ever
Thanks,
Micronax