Question Updating GUI Controls (Delegates?BackgroundWorker? Threading)

xGhost

Member
Joined
Feb 8, 2010
Messages
21
Programming Experience
1-3
Hey.

I've been trying out the new parallel loops in the .net framework 4.0 which handles most threading etc.
Now I got an application which doesn't really need multithreading, rather than 1 seperate thread to do the work.
One of the major problems I always had is update controls in a thread safe way. If you put all your code in 1 form, it isn't that hard to do. But when you got more than one class it requires more I guess.

My question is, how can I update my status controls (labels, progressbar) in a thread safe way without my app getting frozen.

Program structure:
*GUI form with all the controls, mainly a start and some other buttons and listbox and a couple of labels who have to be updated and a progressbar.
*Worker class who does a loop, in this loop there must be a callback to the form which updates the GUI controls. This class can ask info from the third class.
*Another class which is called in the worker class for a couple of times in the loop, which does some work on its own.

Basicly I first thought about delegates in this way:

In the GUI form, I make an instance of the worker class. Then when I click on start I call a method from the worker class which does a loop in this way:
VB.NET:
Worker.DoSomething(True, New StatusDelegates.StatusDelegate(AddressOf StatusMessage)

Invoking a control in the GUI:
VB.NET:
Public Sub StatusCheckedTextbox(ByVal message As String)
        If Me.txtChecked.InvokeRequired Then
            Me.Invoke( _
                New StatusDelegates.StatusCheckedTextbox(AddressOf StatusCheckedTextbox), _
                New Object() {message})
        Else
            Me.txtChecked.Text = Me.txtChecked.Text & message
        End If
    End Sub

I got a statusdelegates class:
VB.NET:
Public Delegate Sub StatusCheckedTextbox(ByVal message As String)
... other delegates 
End Class

In the worker class in the loop:
VB.NET:
If Not StatusCheckedTextbox Is Nothing Then
                                Application.DoEvents()
                                StatusCheckedTextbox(message)
                            End If
----------------------------------------------------------------------

Main problem doing this is that the GUI still freezes or doesn't freeze but doesn't update untill all the work is done, which is in a way logical.
This can be solved using a backgroundworker (or creating a different thread, but I'd rather work with the backgroundworker), but how can I pass information then in a proper way?

Do I still need those delegates then? I know you can pass back information from the BGW like a progress integer, but I atleast need to update 4 labels, change the index from two listboxes, updating a log textbox and display the progress in a progressbar. And that all or a part of them or a combination (dynamic to the situation) in the loop in the workerclass.

Where do I need to declare the backgroundworker then? I guess still in the GUI form (since you cant just put heave code on the main form (aka call of the method which performs a loop from the workerclass), or it'll freeze).
 
Last edited:
know you can pass back information from the BGW like a progress integer
There is a 'state As Object' parameter also where you can put anything you like. For example you can pass on a class instance containing extended event info.
 
There is a 'state As Object' parameter also where you can put anything you like. For example you can pass on a class instance containing extended event info.

Where do I need to declare the backgroundworker then? Since if I would declare it in the workerclass, it still needs to have delegates in order to be able to get to the GUI form?
If I declare it in the GUI then the workerclass doesn't know anything about the GUI form. Since in the dowork there would only be a call of the workerclass.dosomething() where in that class the loop occurs.
Its quite simple to work with the backgroundworker on 1 form, when all you code is in 1 form. But I do the actual work in a worker class.

I'm quite a mess with updating gui controls in a proper way :p.
 
- either you have to let the class know what controls to update, which creates a tight coupling between UI and your worker class and is generally bad design,
- or you can define events in worker class that you raise to notify any listener about something. Listener can then act accordingly and update the appropriate UI. Event Statement
- another option, that something in between, is to pass the BW reference to the worker class, and use it to ReportProgress.
 
Back
Top