How to keep GUI responsive during DB query?
Obviously it can be done, since commercial applications commonly have animated wait dialogs to let you know that the app is working. Does anyone know how I can do it?
Obviously it can be done, since commercial applications commonly have animated wait dialogs to let you know that the app is working. Does anyone know how I can do it?
You might want to look at the documentation for System.Threading.Thread
Dim thread As New Threading.Thread(AddressOf DoQuery)
thread.Start()
Hi Ben,
If you're performing an asynchronous operation and need to update UI from the process or after it completes, the BackgroundWorker component (new for Whidbey) is a great option.
- In the "Components" section of the Toolbox, you'll see a component called "Background Worker". Drag it onto the form you're calling the query from.
- Jump to code for the form
- Handle the DoWork Event on the BackgroundWorker. You can put your DB query in this event handler
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
' Call DB Query here...
End Sub
- If you want to update the UI while the Query is taking place (i.e., progress bar), handle the ProgressChanged Event. Ditto for the RunWorkerCompleted Event.
- Now all you need to do is tell the BackgroundWorker when to start doing its work:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click With Me.BackgroundWorker1 .WorkerReportsProgress = True .WorkerSupportsCancellation = True .RunWorkerAsync() End With End Sub |
I hope this helps!
Joe
The VB Team
Is there a method for passing arguments to the BackgroundWorker component? How would you suggest doing this?
Hi Ben,
I would still stay the path using BackgroundWorkerProcess rather than coming up with your own ThreadingScheme. You will save a lot of time and pain.
There is a way to pass arguments in a threadsafe way using BWP. You just need to set an argument when calling BWP.RunWorkerAsync(argument). You can fetch that data at anytime using the e.Argument field passed into the event handlers. You can also pass data results using the same trick via the e.Result property.
Here is a sample pulling it together:
Private Sub btnRunQuery_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRunQuery.Click Me.BackgroundWorker1.RunWorkerAsync(Me.txtFilterString.Text) End Sub Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork Dim filterString As String = TryCast(e.Argument, String) If filterString IsNot Nothing Then 'call database and retrive data object, e.g. e.Result = dataComponent.getData(filterString) 'note returned data is stored in e.Result End If End Sub Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompletedDim returnedData As DataTable = TryCast(e.Result, DataTable) Me.bindingSource.DataSource = returnedData End Sub |
Hope this helps. Let us know.
Paul Yuknewicz
Visual Basic