Having issues updating a field on a form from a background thread using SynchronizationContext

  • Thread starter Thread starter scott trowbridge
  • Start date Start date
S

scott trowbridge

Guest
I’m developing a test application designed to test the feasibility of utilizing “SynchronizationContext” in a new application we’re designing.


As an overview, we setup a standard vb.net project, then layout a basic form where we define out “Synchronizationcontext”

Private uiContext As SynchronizationContext = SynchronizationContext.Current


We’re running this “Test” function in a background thread, so we setup the necessary “Handlers”, etc

AddHandler processWorker.DoWork, AddressOf Test

AddHandler processWorker.ProgressChanged, AddressOf processworker_progresschanged

processWorker.WorkerReportsProgress = True

processWorker.WorkerSupportsCancellation = True




Under a standard click event, we fire off the background task

processWorker.RunWorkerAsync()

Still located on the form class, we load the our code that does all of our test work. But it is important to note that we’re passing in the “uiContext” we created above and initialized when this form is loaded.

Dim _class As New Class1

_class.test1(uiContext)


The application runs down to our ‘Test’ sub and again being careful how we manage the context.

Public Sub Test(ByVal _uicontext As SynchronizationContext)

Dim uiContext As SynchronizationContext = TryCast(_uicontext, SynchronizationContext)


From here, we do a lot of work (on a background thread) and now we need to update a text field on our form which is running on the Main Thread from our working thread.

uiContext.Send(Sub()

update_UI_Objects(Me.Box3, "Text", row.Item("account_number").ToString)

End Sub, uiContext)



NOTE: In the call above we are using a function named ‘update_UI_Objects” which is located in our form. We pass in the field we need to update, the property and finally the value.



When this code runs in debug mode and we reach this point we can step through this line of code and it takes us correctly back to the form and puts us on the “Main Thread” (which is great).


Now that weve return back to our form, we are now ready to update the UI. The fields passed in are our field (were updating) as an object, the property to update (in this case "Text" and finally a value (i.e. " 22222")

Public Sub update_UI_Objects(ByVal _Object As Object, _

ByVal _Property As String,

ByVal _value As Object)

Lines of code

  1. L_UIWrapper.SetProperty(_Object, _Property, _value)
  2. Dim _obj = L_UIWrapper.GetProperty(_Object, _Property)
  3. L_UIWrapper.InvokeMethod(_Object, "Refresh", Nothing)



The three lines of code above allow us to call routines located in a wrapper class (below). They do the following:

  1. We set the property
  2. We get the value that was just set (test purposed only)
  3. Then we invoke a method on the textbox to refresh the field and display the value on the form.


During testing the value is set correctly, because the variable ‘_obj’ contains the correct value when executing the ‘GetProperty’

The InvokeMethod doesn’t force the field to display the value on the form.

Here’s the question: How can I get the data which is contained on the textbox to display on a form?


Wrapper Code (sub/functions)


Public Sub SetProperty(ByVal obj As Object, ByVal sProperty As String, ByVal oValue As Object)

Dim oParam(0) As Object

oParam(0) = oValue

obj.GetType().InvokeMember(sProperty, BindingFlags.SetProperty, Nothing, obj, oParam)

End Sub

Public Function GetProperty(ByVal obj As Object, ByVal sProperty As String, ByVal oValue As Object) As Object

Dim oParam(0) As Object

oParam(0) = oValue

Return obj.GetType().InvokeMember(sProperty, BindingFlags.GetProperty, Nothing, obj, oParam)

End Function

Public Function InvokeMethod(ByVal obj As Object, ByVal sProperty As String, ByVal oValue As Object) As Object

Dim oParam(0) As Object

oParam(0) = oValue

Return obj.GetType().InvokeMember(sProperty, BindingFlags.InvokeMethod, Nothing, obj, oParam)

End Function

Continue reading...
 
Back
Top