rutledgj
asked on
vb.net How to update UI from task
Ok. So I'm trying to use the task stuff to do parallel programming. I can't figure out how to update a gui label from a task.
I have Downloads class with method DownloadPatientData(V as Vendor) Vendor is a class to hold data.
in main form I have:
While VendorQueue.Count > 0
Dim v As Vendor = Nothing
If VendorQueue.TryDequeue(v) = True Then
threadCount += 1
Console.WriteLine("Process ing Org " & v.Org)
v.DrFirstVersion = DrFirstVersion
Dim d As New Downloads
d.ThreadName = "t" & CStr(threadCount)
Dim t As Task = Task.Factory.StartNew(Sub( ) d.DownloadPatientData(v))
End If
End While
So over in the DownloadPatientData method how can I write back to the gui label (lblStatus)?
In regular threading you could add a event handler. What do you do here?
I have Downloads class with method DownloadPatientData(V as Vendor) Vendor is a class to hold data.
in main form I have:
While VendorQueue.Count > 0
Dim v As Vendor = Nothing
If VendorQueue.TryDequeue(v) = True Then
threadCount += 1
Console.WriteLine("Process
v.DrFirstVersion = DrFirstVersion
Dim d As New Downloads
d.ThreadName = "t" & CStr(threadCount)
Dim t As Task = Task.Factory.StartNew(Sub(
End If
End While
So over in the DownloadPatientData method how can I write back to the gui label (lblStatus)?
In regular threading you could add a event handler. What do you do here?
ASKER
Well this compiles but the code never gets to the Me.lblStatus.Text = txt
It does the Me.Invoke section but nothing else.
It does the Me.Invoke section but nothing else.
The method to recieve the event inthe main form should be:
Public Class Form1
Private Sub dld_Status(ByVal txt As String)
If Me.InvokeRequired Then
Me.Invoke(New Action(Of String)(AddressOf dld_Status), New Object() {txt})
End If
Me.lblStatus.Text = txt
End Sub
End Class
ASKER
that doesn't work either. Never gets to lblstatus.text = txt
ASKER
I have also noticed that raising the event from the DownloadPatientData method, even though it doesn't update the label, prevents the application from closing. It gets stuck in the task.waitall call. Removing the raiseevent allows it to complete as normal.
There must be a different way to update the gui using tasks.
There must be a different way to update the gui using tasks.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
This is the complete code in the main form. When the tasks complete I close the app.
While VendorQueue.Count > 0
Dim v As Vendor = Nothing
If VendorQueue.TryDequeue(v) = True Then
threadCount += 1
Console.WriteLine("Process ing Org " & v.Org)
v.DrFirstVersion = DrFirstVersion
Dim d As New Downloads
d.ThreadName = "t" & CStr(threadCount)
d.MyVendor = v
AddHandler d.ThreadFinished, AddressOf ThreadUpdateHandler
' lstTasks.Add(Task.Factory. StartNew(S ub() d.DownloadPatientData()))
Dim t As New Task(Sub() d.DownloadPatientData())
t.Start()
lstTask.Add(t)
End If
End While
Task.WaitAll(lstTasks.ToAr ray)
Application.Exit()
I understand what you are saying. A catch 22. So what is the alternative?
While VendorQueue.Count > 0
Dim v As Vendor = Nothing
If VendorQueue.TryDequeue(v) = True Then
threadCount += 1
Console.WriteLine("Process
v.DrFirstVersion = DrFirstVersion
Dim d As New Downloads
d.ThreadName = "t" & CStr(threadCount)
d.MyVendor = v
AddHandler d.ThreadFinished, AddressOf ThreadUpdateHandler
' lstTasks.Add(Task.Factory.
Dim t As New Task(Sub() d.DownloadPatientData())
t.Start()
lstTask.Add(t)
End If
End While
Task.WaitAll(lstTasks.ToAr
Application.Exit()
I understand what you are saying. A catch 22. So what is the alternative?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Open in new window
Now, in your form, create a method to receive the event and update the label:
Open in new window
Finally, use AddHandler() to wire up the event when the instance of Downloads is created:
Open in new window