skip to Main Content

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


  1. in time_consuming_function(…) you can send some infos to UI using invoke like this (assuming textbox1 exists in UI form):

    sub time_consuming_function(...)
    .... your stuff....
    Me.BeginInvoke(Sub() textbox1.Text = "running...")
    ....
    end sub
    
    Login or Signup to reply.
  2. The effect of Await is that it returns control to the UI until the expression or call that is Awaited completes. It seems to be suited reasonably well to your workflow, you just need to make changes to process_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.

    '(Inside the loop body)
    CurrentOperation = $"Processing {inputPdf} into {outputPdf}..."
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(CurrentOperation)))
    Await Task.Run(...)
    

    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search