CSLA 4.5.3 hangs in synchronous Save()

CSLA 4.5.3 hangs in synchronous Save()

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


JonM posted on Tuesday, October 09, 2012

I'm using:

Now I'm trying to get the code running in Winforms.  The SaveAsync() works great from winforms.  However, the Save() just hangs forever.  Inside my Dataportal_Update I'm using an HttpClient + webapi to save my object to an http rest service.  I'm not sure why but basically the call to the httpclient hangs in this mode. Is this a deadlock or something?  Does it have something to do with having an await inside of the dataportal task method?

HttpClient client = new HttpClient();

var response = await client.PutAsJsonAsync<T>(url.ToString(), item);

 

 

RockfordLhotka replied on Tuesday, October 09, 2012

There are some different behaviors depending on whether the DataPortal_XYZ methods are running local or remote.

It sounds like you are running local with an async DP_XYZ, but a sync "client-side" call. I just ran into this as a blocking issue today, and I am not convinced it is solvable. In other words it might be a scenario that can't be supported, but I'm not sure yet.

Most notably, if the client-side code does a sync call, that blocks the UI thread, and as a result the async callback from the background process can't be marshaled onto the UI thread, because the UI thread is blocked. There's nothing I can really do about that of course, because it is the await code itself that's trying to do this marshalling, and if you've blocked the UI thread then it is blocked...

JonM replied on Wednesday, October 10, 2012

Rocky,

I am using a local dataportal, because I'm calling a webapi backend.  I was worried it was a UI thread deadlock issue.  I've been running into that a lot with 4.5 when I do an async call inside an sync call.  I agree with you that there is little you can probably do about it.

Thanks,

Jon

RockfordLhotka replied on Wednesday, October 10, 2012

I was thinking that perhaps I can detect that the following are true:

  1. Client made a sync call
  2. "Server-side" code is in ExecutionLocation.Client
  3. Target method (DP_XYZ or factory method) returns Task

In that case, the data portal could explicitly spin up a background thread on which it could invoke the target method. The data portal would synchronously wait for that thread to complete, but on that background thread the code could use async/await without blocking, because the await would marshal to the explicit background thread, not to the UI thread.

I don't want to try something that major/complex for the current release, because I don't have confidence I can get something like that tested and stable for an Oct release.

Still, it might be worth exploring for a subsequent release.

JonM replied on Wednesday, October 10, 2012

I agree.  That will take a lot of time to test.  I've spent my fair share debugging (crying over) multi-thread/cross-thread issues over the years. 

My current solution is not to make Async calls from inside my dataportal methods.  The WebAPI samples on the web all show use the HttpClient class with Async methods.  This class doesn't have Synchronous versions.  I've switch to calling WebAPI code using the HttpWebRequest which does have sync methods in full .NET.  This is was easy because I already had to figure out how to use HttpWebRequest in Silverlight (except we use its async methods there) because it doesn't have an equivalent HttpClient.  This solves the problem totally for me.

Thanks again for the help in understanding this!

 

Copyright (c) Marimer LLC