I’m trying out some async code to avoid locking up the UI while my program runs a time-consuming function (using Visual Studio 2022).
Here’s what I’ve got so far – the program is running through pdf filename entries from a datagrid and performing the function on the filenames it finds:
Async Sub process_files()
For Each myrow In DGV_inputfiles.Rows
inputPDF = myrow.cells("col_filenamefull").value
outputPDF = myrow.cells("col_outname").value
Await Task.Run(Sub()
time_consuming_function(inputPDF, outputPDF)
End Sub)
Next
End Sub
At the moment, the program is not waiting for the ‘time_consuming_function’ to finish, so it’s getting to the end of the sub before some of the output files are generated – so it appears to the user that it has finished when it’s actually still working.
I believe the solution is something to do with returning a value from the function and waiting for it, but I can’t quite see how it works – could anyone help please?
2
Answers
in time_consuming_function(…) you can send some infos to UI using invoke like this (assuming textbox1 exists in UI form):
The effect of
Await
is that it returns control to the UI until the expression or call that isAwait
ed completes. It seems to be suited reasonably well to your workflow, you just need to make changes toprocess_files
to be more user-friendly.For example, you could have something in the UI update with the file that is currently being processed, and change it at the line before
Task.Run
.e.g.
You could disable UI controls before the
For
loop and re-enable them when it finishes.The benefit of
Await
is that these changes will be easy, and the logical flow of the routine will be easy to follow.Be aware that any
Await
presents an option for re-entrant code as the user may interact with the UI (this is true even for cases where everything is running on one thread as with async internet or I/O operations).If you haven’t done so already, I would recommend to read everything Stephen Cleary has written about asynchronous operations in .NET.