Kallol Kallol - 6 months ago 78
Vb.net Question

Task.Run - Handling exceptions

I am having a function as below (kept only relevant code for this example):

Public Async Function RefreshCompanyCodesAsync() As Task(Of Boolean)
For ctr=1 to 2000
Await Task.Delay(1000).ConfigureAwait(False)
If ctr=5 Then Throw New ApplicationException("Why 5?")
Next
return true
End Function


As you can see, I am generating an exception when ctr = 5 just to check how the exception will be handled in the UI.

I then call this function inside a button click
Async
event:

Dim task1 = Task.Run(Sub()
RefreshCompanyCodesAsync()
End Sub)
Dim cTask = task1.ContinueWith(Sub(antecedent)
If task1.Status = TaskStatus.RanToCompletion Then
MsgBox("All done")
ElseIf task1.Status = TaskStatus.Faulted Then
MsgBox(task1.Exception.GetBaseException().Message)
End If
End Sub)


The task runs to completion instead of being faulted. I am guessing thats because a wrapper task runs to completion instead of the original task that threw an exception. However, am not sure how to get to the original task and handle the exception.

I have tried with
Await
.

Try
Await RefreshCompanyCodesAsync()
Catch ax As AggregateException
MsgBox(ax.Message)
Catch ex As Exception
MsgBox(ex.Message)
End Try


Exceptions get caught here, but the problem is I need to start multiple functionalities in parallel of which
RefreshCompanyCodesAsync
is only one of them. To do that, I believe launching those functionalities via Task.Run would be the best bet.

The actual functionality of the worker function in my case involves extensive DB and
HttpClient
activity and during this time, the UI responsiveness is driving me towards going in for
Task.Run
or
Factory.StartNew


Also, have tried launching the task and Waiting for it so as to ensure evaluation of the result. However, my UI gets blocked when I do
Task.Wait
.

Any help is really appreciated.

usr usr
Answer

Probably, what you want is

Dim task1 = RefreshCompanyCodesAsync()

That way there is no wrapper task. RefreshCompanyCodesAsync already is non-blocking which is important so that you don't freeze the UI.

You should avoid ContinueWith. Prefer await because it marshals you back to the UI thread.

I'll need to write this in C#:

var task1 = RefreshCompanyCodesAsync();
await Task.WhenAny(task1); //Wait without throwing.
MessageBox.Show(task1.Status.ToString());