async factory method confusion

async factory method confusion

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


TSF posted on Friday, July 29, 2011

I'm confused on how to properly implement async factory methods for both WPF & Silverlight - are there differences between the two?  In Rocky's new DataAccess e-book, he lists examples as shown below.  He makes a point to state that, for Silverlight and WP7, the CompletedHandler must be invoked when the method is complete.  However, in the EncapsulatedInvoke sample project, I don't see any data portal methods that actually do this (for example, the Execute DP method in the OrderShipper class never invokes the handler).

Is invoking the handler required in certain async scenarios and not in others?  Thanks.

Tim

public void DataPortal_Fetch( int id, Csla.DataPortalClient.LocalProxy<PersonEdit>.CompletedHandler handler) {

try {

 // invoke external DAL here (encapsulated invoke) // or implement DAL code here (encapsulated implementation)

handler(this, null);

}

catch (Exception ex)

{ handler(null, ex); }

 

JonnyBee replied on Friday, July 29, 2011

Hi,

The DataPortal_XYZ (like DataPortal_Fetc) should always be coded as synchronous methods that may be called on the client or on a server and will  normally NOT have any exception handling (try/catch) 

The DataPortal as such offers both sync and async methods for WPF /WinForms but in SL there is only async methods.My point is that the asyn jhandling is actually in the DataPortal and often in the static factory methods or fby directly calling the async methods on the DataPortal.

The difference between SL and WPF is that

WPF and SL

    public static void GetProjectList(string name, EventHandler<DataPortalResult<ProjectList>> callback)
    {
      var portal = new DataPortal<ProjectList>();
      portal.FetchCompleted += callback;
      portal.BeginFetch(new SingleCriteria<ProjectList, string>(name));
    }

or

      var portal = new DataPortal<ProjectList>();
      portal.FetchCompleted += (o,e) => {
                   // this code is called after the async method returns
           }
      portal.BeginFetch(new SingleCriteria<ProjectList, string>(name));

The DataPortal will (internally) use a BackgroundWorker to do the async call.

So in essence - your DataPortal_XYZ (DAL) methods should not know or care if they are called by an async or sync call on the DataPortal. Async is handled by the DataPortal and you code calling BeginFetch, BeginCreate etc on the DataPortal.

TSF replied on Friday, July 29, 2011

But why does Rocky include the examples that he did in his e-book where he puts exception handling inside the DP methods?  Where does his code example come into play...what kind of scenario?  On page 6 of his DataAccess e-book, he states the following:

It is critical that the callback parameter be invoked when the method is complete, whether an exception occurs or not. If the callback parameter isn't invoked the data portal won't know that the method has completed and the application will be stuck thinking the data access operation is still running.

 And to do that, he wraps the DP code inside a try/catch block.  Again, the example code I give in my original post is Rocky's, not my own.  Thanks.

JonnyBee replied on Friday, July 29, 2011

Context for that chapter is:

If the remote service call is asynchronous, then the DataPortal_XYZ method must also be
asynchronous. This means that the method must accept a callback parameter so the calling code
can be notified when the asynchronous operation is complete.

Rocky\s sample in the book is quite specific context for a scenario where:

IE: The Data Access is async in DataPortal_Fetch and you need to send the async callback handler as a parameter and invoke it from  the Data access method.

For many scenarios you'll want to use the async DataPortal and have sync code DataPortal_XYZ calls. This allows you to call serverside code for DataAccess using Csla DataPortal.

I would expect that you could also use WaitHandle.WaitOne as an alternative in DataPortal_Fetch for this scenario.

 

 

 

 

TSF replied on Friday, July 29, 2011

That makes sense.  Going back to the two factory examples you gave previously, how do you call those methods via Silverlight?  Would it be something like this?

CustomerInfoList.GetCustomerList(txtSearch.Text, (o, ea) =>
{
   customerInfoListVMViewSource.Source = ea.Object
as CustomerInfoList;
}

JonnyBee replied on Friday, July 29, 2011

Yes, except that you should always check for an exception in the data portal callback method with

if (e.Error != null) {
     // show message to user
}
else {
   customerInfoListVMViewSource.Source = ea.Object as CustomerInfoList;
}

 

Copyright (c) Marimer LLC