Trying to Implement the Book's example of Asynchronous Fetch

Trying to Implement the Book's example of Asynchronous Fetch

Old forum URL: forums.lhotka.net/forums/t/7040.aspx


shawndewet posted on Wednesday, June 03, 2009

I'm trying to implement Asynchronous Fetching in my business object library.  Using the following example Rocky provides in his Expert VB 2008 Business Objects book (p417)

Public Shared Sub BeginGetCustomerEdit(ByVal callback _

As EventHandler(Of DataPortalResult(Of CustomerEdit)))

Dim dp = New DataPortal(Of CustomerEdit)

AddHandler dp.FetchCompleted, AddressOf FetchComplete

dp.BeginFetch(New SingleCriteria(Of CustomerEdit, Integer) _

(123, callback))

End Sub

(Replace "CustomerEdit" with my business object type)

Visual Studio gives me the squigly line under CustomerEdit, with the error saying:

'Csla.Server.DataPortalResult' has no type parameters and so cannot have type arguments.

Can anybody please advise as to how they have done this; what am I missing? (I'm using CSLA v3.6.2.0)

shawndewet replied on Wednesday, June 03, 2009

Just want to bump this up...Rocky I see you're in the Forums right now...any idea on what the problem might be here?  I've taken the code right out of your book and tried to use it, but to no avail.

RockfordLhotka replied on Wednesday, June 03, 2009

  Public Shared Sub GetCustomer(ByVal id As Integer, ByVal handler As EventHandler(Of DataPortalResult(Of CustomerEdit)))

    Dim dp = New DataPortal(Of CustomerEdit)
    AddHandler dp.FetchCompleted, AddressOf FetchCompleted
    dp.BeginFetch(New SingleCriteria(Of CustomerEdit, Integer)(id), handler)

  End Sub

  Private Shared Sub FetchCompleted(ByVal o As Object, ByVal e As DataPortalResult(Of CustomerEdit))

    Dim handler = DirectCast(e.UserState, EventHandler(Of DataPortalResult(Of CustomerEdit)))
    handler.Invoke(o, e)

  End Sub

RockfordLhotka replied on Wednesday, June 03, 2009

Oh, I see, sorry.

If you read the error text carefully, it says you are trying to use Csla.Server.DataPortalResult.

You need to be using Csla.DataPortalResult.

You probably have the wrong Imports at the file or project level, so it is using the wrong namespace.

shawndewet replied on Wednesday, June 03, 2009

Ok I'm officially feeling sheepish!!!!  Wrong Imports!!!! Thanks Rocky.

shawndewet replied on Wednesday, June 03, 2009

Awesome I got this to work perfectly now.  That it, until I tested for how it handles a problem on the database (in this case, I miss-spelled the ConnectionString key).  The problem is in the FetchCompleted method:

Private Shared Sub FetchCompleted(ByVal o As Object, ByVal e As DataPortalResult(Of ArCustomerCollection))

Dim handler = DirectCast(e.UserState, EventHandler(Of DataPortalResult(Of ArCustomerCollection)))

handler.Invoke(o, e)

End Sub

The problem is that when there is an error getting the data out of the database, then e.UserState in this method is null; resulting in handler being null;  resulting in an Object Reference Not Set error on the "handler.Invoke(o,e)" call.  I've tried putting in a check like:

If Not e.Error Is Nothing Then

Throw e.Error

End If

But the problem is that this FetchCompleted method does find an appropriate Try..Catch..block on the UI thread, resulting in the "An unhandled exception has occurred in your application" message popping up.  Of course if I use the Application_UnhandledException event to catch the exception I can display an appropriate messagebox to the user.  But the core problem here is that the callback method in the gui (the one that is supposed to be called by "handler.invoke(o,e)") never gets invoked, and that method contains the code that is meant to reset the state of the GUI after the async call.

So my question is...Is it right that in the FetchCompleted method above the e.UserState is null when e.Error is NOT null?  Surely e.UserState should still contain the callback method so that it can be invoked and handle any exception that is in e.error?

 

RockfordLhotka replied on Wednesday, June 03, 2009

This sounds like it could be a bug. Yes, UserState should be consistent regardless of whether there was an exception on the server.

 

Rocky

 

 

From: shawndewet [mailto:cslanet@lhotka.net]
Sent: Wednesday, June 03, 2009 2:59 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Trying to Implement the Book's example of Asynchronous Fetch

 

Awesome I got this to work perfectly now.  That it, until I tested for how it handles a problem on the database (in this case, I miss-spelled the ConnectionString key).  The problem is in the FetchCompleted method:

Private Shared Sub FetchCompleted(ByVal o As Object, ByVal e As DataPortalResult(Of ArCustomerCollection))

Dim handler = DirectCast(e.UserState, EventHandler(Of DataPortalResult(Of ArCustomerCollection)))

handler.Invoke(o, e)

End Sub

The problem is that when there is an error getting the data out of the database, then e.UserState in this method is null; resulting in handler being null;  resulting in an Object Reference Not Set error on the "handler.Invoke(o,e)" call.  I've tried putting in a check like:

If Not e.Error Is Nothing Then

Throw e.Error

End If

But the problem is that this FetchCompleted method does find an appropriate Try..Catch..block on the UI thread, resulting in the "An unhandled exception has occurred in your application" message popping up.  Of course if I use the Application_UnhandledException event to catch the exception I can display an appropriate messagebox to the user.  But the core problem here is that the callback method in the gui (the one that is supposed to be called by "handler.invoke(o,e)") never gets invoked, and that method contains the code that is meant to reset the state of the GUI after the async call.

So my question is...Is it right that in the FetchCompleted method above the e.UserState is null when e.Error is NOT null?  Surely e.UserState should still contain the callback method so that it can be invoked and handle any exception that is in e.error?

 



shawndewet replied on Thursday, June 04, 2009

Any chance of it being resolved in v3.6.3?

JoeFallon1 replied on Thursday, June 04, 2009

I would bet against it.

After all the userstate code is specific to VB and Rocky does not support VB anymore!

When VB 10 comes out this will all go away anyway as it will support multi-line lambdas.

Joe

RockfordLhotka replied on Thursday, June 04, 2009

That's not entirely true Joe.

The idea of allowing UserState to flow through an async operation is a core
part of the async pattern in .NET. While lambdas do help reduce the need for
the concept, I don't know that they entirely eliminate the value.

After looking at the code though, a 100% solution is probably impossible due
to the way the BackgroundWorker component is designed. Interestingly enough,
it doesn't support the UserState concept - which seems wrong to me - but we
live in the world that is, not the world we'd like.

But I can implement a solution that'll work maybe 99.9% of the time. In
fact, it will only not work when something aborts the background thread or
something on the background thread throws an uncatchable exception - and
those are pretty rare scenarios that probably indicate your entire app (or
even OS) is crashing.

Rocky

RockfordLhotka replied on Thursday, June 04, 2009

I hope so.

 

From: shawndewet [mailto:cslanet@lhotka.net]
Sent: Thursday, June 04, 2009 7:08 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Trying to Implement the Book's example of Asynchronous Fetch

 

Any chance of it being resolved in v3.6.3?

RockfordLhotka replied on Thursday, June 04, 2009

shawndewet:
Any chance of it being resolved in v3.6.3?

Yes, absolutely, the fix is in svn now.

Copyright (c) Marimer LLC