CSLA 4.5, Async & Csla.Data

CSLA 4.5, Async & Csla.Data

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


g.beraudo@castsoftware.com posted on Tuesday, August 14, 2012

Hi,

Are there any move to make the Csla.Data classes 'Async ready'?

For insance, getting a TransactionManager (opening connection & transaction) with the new 4.5 async APIs added to ADO.NET?

This is an open question.
We are looking benefits we can get from upgrading to .NET 4.5 (from CSLA 4.3 to CSLA 4.5) with .NET 4.5. As we will rewrite key Dataportal_Update with the Async spirit on a 2 tiers winform application mainly monothreaded application, opening DB connections is also part what make our application unresponsive (when not on the LAN).

Regards,

Gilles

JonnyBee replied on Tuesday, August 14, 2012

To start with - in CSLA 4.5 you can return Task<T> from DataPortal_XYZ methods and thus make the Data Access methods run async (even if the DataAccess itself is sync and you have a 3-tier application).

You also have DataPortal.XYZAsync methods that return Task<T> to make the client run asynchronous (rather than use DataPortal.BeginXYZ with a callback in the "old" style).  

IE: You can write code like this in the client:

As a result, it is now possible to use the new async and await keywords to consistently call the data portal in .NET, WinRT, and Silverlight 5.

var obj = await DataPortal.FetchAsync<Customer
Edit>();

From what is already in the brugtracker (http://www.lhotka.net/cslabugs) this is planned for CSLA 4.5:
http://www.lhotka.net/cslabugs/edit_bug.aspx?id=1077 : SafeDataReader needs to support new async DR features

g.beraudo@castsoftware.com replied on Tuesday, August 14, 2012

Thanks for the clarification.

It seems I did not look carefully enough inside the bugtracker, thanks for the link!

I alread played a little with CSLA 4.5 (with .SaveAsync), result is really really great. We can really improve responsiveness with very little development/maintenance costs!

Gilles

JonnyBee replied on Tuesday, August 14, 2012

Yes, I believe the DataPortal.XYZAsync methods will go a long way in a 2-tier application to make the DataAccess run async from the client without further changes in the DataAccess code. This will make your application a lot more responsive to the user.

Plus - you can also use

try
{
     var obj = await DataPortal.FetchAsync<Customer Edit>();
}
catch (Exception ex)
{
    // Exception handling code here
}

just as it was when the code was synchronous.

 

 

 

bchase replied on Friday, August 24, 2012

 

 

 

 

 

I am attempting to use the 4.5 alpha in a Silverlight 5.0 application in order to use the new async/await features.  The following contrived example does not compile under VS11/.NET 4.5/Silverlight 5.0/CSLA 4.5. 

Error:

Cannot find all types required by the 'async' modifier. Are you targeting the wrong framework version, or missing a reference to an assembly?

 How does one use the async feature within Silverlight client in tandem with CSLA 4.5 alpha? 

public

 

 

static async Task<Customer> GetCustomerByCustomerIdAsync( Guid id)

{

 

try

{

 

 

 

 

Task<Customer> obj = await DataPortal.FetchAsync<Customer>(new CritereaPassenger(id));

return obj;

}

 

 

 

catch (Exception ex)

{

 

 

 

// Exception handling code here

}

}

 

Thanks for you help

JonnyBee replied on Friday, August 24, 2012

You must add a reference to AsyncTargetingPack to the SL project from NuGet.

bchase replied on Monday, August 27, 2012

I had misunderstood the documentation on AsyncTargetingPack and believed that with VS11 and 4.5 .NET, the pack was unneeded.  But with Silverlight 5.0, it is required no matter as you point out. 

Next question:  In the Silverlight client side, why does one function hang and whereas the other does not? Both appear to legal forms from what i have read. The following is simplified code of the problem.  

This hangs:

public static async Task(MyClass) GetMyClassById(Guid Id)

{

   MyClass myclass = await DataPortal.FetchAsync<MyClass>(new CriteriaMyClass(Id)); // hangs here... 

  return myclass; // never makes it here

}

Whereas this does not hang and I can access the instance of the MyClass object in the dictionary:

static Dictionary<Guid,MyClass>  ListOfReturns = new Dictionary<Guid,MyClass>();

public static async void GetMyClassById(Guid Id)

{

     MyClass myclass = await DataPortal.FetchAsync<MyClass>(new CriteriaMyClass(Id)); // does not hang

     ListOfReturns.Add(Id,myclass); // adds the instance of MyClass correctly

}

Thanks in advance

 

RockfordLhotka replied on Monday, August 27, 2012

The async/await keywords aren't always as simple as they might appear on the surface.

The problem I think you are encountering is one I've been fighting with as well. If you block the UI thread by synchronously calling an async method, and that async method ultimately does something (like call WCF) that has a callback occur on a background thread, the await keyword can't marshal the call back onto the UI thread because the UI thread is blocked.

The secret to success is to NEVER block the UI thread with a synchronous call. In other words, the code that's calling your GetMyClassById method must await the result in order to avoid blocking the UI thread.

bchase replied on Wednesday, September 05, 2012

Rocky,

Thank you for the reply.  

As I understand it, the async and await keywords in conjunction with the method name ending in "Async"  are forcing the compiler to output code that essentially causes an otherwise synchronous call to become asynchronous for the line that contains "await". That is, the method cannot continue/regain control on the "await" line until the information is returned.  If one uses the "Task" keyword, this is further this is further complicated -- but let's keep it simple.

My question... I am trying to poke holes into the last method that I used in which I put the await results into a static dictionary and used that result -- from the dictionary -- after the return of the "GetMyClassById" method. This methodology does not hang the UI thread and the results are correct.  The newest information from the database would be represented in the object (MyClass) in the dictionary. I just don't like this methodology -- but it works in the Silverlight client.  What am I missing?

As a side note, I cannot find within the Silverlight client a methodology that uses the Task<TResult> in conjuction with the async and await keywords that allows for a call to the DataPortal.FetchAsync without hanging the UI thread.  

Bruce

RockfordLhotka replied on Wednesday, September 05, 2012

That is tricky, and not just in SL.

The short answer to solving this is to await the object factory (or data portal) call within an async void method - often a UI event handler.

When an async void method is invoked it will return immediately, and your await inside that method therefore doesn't block the UI thread.

For example, I usually initialize my viewmodel as the page loads. So you can make the Loaded event handler async, then do the await in that handler.

For that matter, I've taken to making my viewmodels expose an awaitable InitAsync method (the new ViewModelBase does this, delegating to a protected DoInitAsync method you can override).

Copyright (c) Marimer LLC