Async Callback methods

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I have a program that using BeginInvoke on a Delegate to cause the Save to
execute on the background thread. When the call completes I have a callback
method which executes and updates the UI (after moving back to the main
thread). The problem I have is that if there was an error during the Save
method I want to update the UI differently, but I don't know how to tell from
my Callback method that an error occurred. Here is the basic snippets of
code

Class level delegate:
Private Delegate Function CreateDeductionRequestDelegate(ByVal amount As
Int32) As Int32

Here is my save routine. You will see that I have an error handler around
this method, which displays an error message to the user and logs the error.
Private Function CreateDeductionRequest(ByVal deductionRequestID As
Int32, ByVal deduction As OceanSpray.Trade.Deduction, ByVal filter As
OceanSpray.MasterData.FilterCollection, _
ByVal variableAmountToUse As Decimal, ByVal fixedAmountToUse
As Decimal, ByVal pooledFunds As Boolean) As Int32
Try

OceanSpray.Trade.DeductionRequest.CreateDeductionRequest(deductionRequestID,
deduction, filter, variableAmountToUse, fixedAmountToUse, pooledFunds)
Catch ex As Exception
LogError(ex)
End Try
End Function

In the Save button, you will see that my method I'm calling is call
CreateDeductionRequest and the name of the Callback method is SaveComplete.
I also have an AsyncState object which contains some information about what
I'm saving and is used in SaveComplete routine:
Dim CreateDeductionRequestRoutine As New
CreateDeductionRequestDelegate(AddressOf CreateDeductionRequest)
CreateDeductionRequestRoutine.BeginInvoke(100, _
AddressOf SaveComplete,
TradeDelegateAsyncState)

Finally I have the SaveComplete method which does some stuff to the UI, but
I need to know here if it failed in the Async method
Public Sub SaveComplete(ByVal ar As System.IAsyncResult) Implements
IMdiForm.SaveComplete
If Not Me.Status.InvokeRequired Then
Try
'Check if Save is from TradeFunction
OceanSpray.Common.Push()
If TypeOf ar.AsyncState Is
OceanSpray.Trade.TradeDelegateAsyncState Then
Dim TradeDelegateAsyncState As
OceanSpray.Trade.TradeDelegateAsyncState
'Do some stuff to update UI
Catch ex As Exception
LogError(ex)
Finally
OceanSpray.Common.Pop()
End Try
Else
Dim SaveRoutine As New AsyncCallback(AddressOf SaveComplete)
Me.BeginInvoke(SaveRoutine, New Object() {ar})
End If
End Sub
 
I think you should remove the Try..Catch block from the Save routine,
if there is any error within this function, it will be caught by your
Callback routine.

In your SaveComplete function, not sure why you call Async Callback
function,
this is where you should call your UI update routine, using
Me.BeginInvoke().

Check out this article:
http://msdn.microsoft.com/msdnmag/issues/04/05/BasicInstincts/

Hope it help.
David
 
If I take the error handler out and then and error occurrs in that procedure
it just dies off and I have no way of knowing that the error occurred in my
SaveComplete method. There was nothing special in the SaveComplete method or
the AsyncResult that told me an error had occurred.

To answer your question the SaveComplete method is the UI Update method you
can see that I do a check to see if I need to move back to the UI thread,
which is done in the bottom of the procedure, otherwise it updates the UI.
 
If I take the error handler out and then and error occurrs in that procedure
it just dies off and I have no way of knowing that the error occurred in my
SaveComplete method. There was nothing special in the SaveComplete method or
the AsyncResult that told me an error had occurred.

To answer your question the SaveComplete method is the UI Update method you
can see that I do a check to see if I need to move back to the UI thread,
which is done in the bottom of the procedure, otherwise it updates the UI.
 
If I take the error handler out and then and error occurrs in that procedure
it just dies off and I have no way of knowing that the error occurred in my
SaveComplete method. There was nothing special in the SaveComplete method or
the AsyncResult that told me an error had occurred.

To answer your question the SaveComplete method is the UI Update method you
can see that I do a check to see if I need to move back to the UI thread,
which is done in the bottom of the procedure, otherwise it updates the UI.
 
In your SaveComplete callback function, you have the following code to
call the callback routine again? not sure what you try to do here:

Dim SaveRoutine As New AsyncCallback(AddressOfSaveComplete)
Me.BeginInvoke(SaveRoutine, New Object() {ar})

Also, callback function is always called from the worker thread, not the
main thread
So, you don't need to check for InvokeRequired, because it is required.

Rewrite your callback like this:

Try
OceanSpray.Common.Push()
If TypeOf ar.AsyncState Is OceanSpray.Trade.TradeDelegateAsyncState Then
Dim TradeDelegateAsyncState As
OceanSpray.Trade.TradeDelegateAsyncState
'Do some stuff to update
'**** Call UI update function, using Me.BeginInvoke()
*****
Catch ex As Exception '**** any error from Save will get caught here *****
LogError(ex)

The Try/Catch block will catch any error from your save routine. Since this
is run in the worker thread,
do not directly update any UI here, use Me.BeginInvoke() to call your UI
update function.

Write a UI update function to actually update the UI, and if this
UI update function will be used by both the main thread and work thread then
you would
check for InvokeRequired.

See the reference article
 
My problem is not with updating the UI thread. The way I have it structured
works just fine. My problem is that when an error occurs in the previous
method in the SaveComplete method I don't get any notification that the error
occurred. The try catch in the SaveComplete method only gets hit if an error
occurs in the SaveComplete method not when the error occurrs in the
CreateDeductionRequest method.
 
That's because your Save method has a try/catch block which caught the error
already.
If you remove the try/catch in Save, the error will propagate to the
callback method.
 
Back
Top