Wether to suffer the slings and arrows of (multi-threading)...and background workers...
OK sorry, enough butchering of Shakespeare.
Spent years sitting on CSLA 3.8 watching the trains go by (silverlight, windows phone etc.). I thought for sure I would have upgraded by now, but everytime I feel tempted I sit back and ask myself, what is this going to give me?
After much ado, my business layer has the 2 project scheme where it can compile for silverlight or normal by using linked files and compiler directives. I would say about 10-20% of my business objects are coded for both sync and async. I am forced to behave properly so that full async later won't be a nightmare! Doing this DEFINITELY forced me to see how my coding was based on sync assumptions. I was going to say "bad habits" but I don't know if there is intrinsic badness if sync works fine for our business needs. But maybe it is good just for ones ability to keep up in an increasingly muti-core, parralel, async world of skills out there. So I haven't used my silverlight code yet except for a small demo project that I compile alongside my ASP.NET. Nice to know I am ready to spring into action if need be.
I cannot stress enough the value of doing a small silverlight demo UI that I include in my web solution. I have to ensure it compiles and runs as I develop our web app. This showed me many flaws in my thinking, many assumptions and comfortabilities with the old ways. A curious effect was I gave up some of my unique solutions, and started using the more standard CSLA methods (auto-managed properties etc.) because they solved the problems I WOULD run into if I had to go down the multi-UI road.
My current and only application is an ASP.NET website with no glaring reason to change as it meets most of our needs. Its not super sexy, but we are slowly addressing that by ajaxifying/refactoring ui...and Telerik controls like the new RadAsyncUpload are helping us there.
Async or not
I have had two basic assumptions on the back burner of my mind for the last couple years:
1. It would be good if I would go back and make all my business layer fully Async-able (lack of better worrd)
2. It would be good if I would just make all my code async...and get used to just doing it that way. Mostly factory methods and business rules.
#2 is the key to my question!
I spent the last two days digging into the guts of understanding multi-threading/Async/BackgroundWorker from ASP.NET. What a nightmare of knowledge I didn't know I needed and not sure I want now that I have it! Yick. But I must say I was completely surprised by a truism from Rocky..."Stay away from spinning up Background workers in ASP.NET"
See the 2 following comments from Rocky...please trust me and him if you haven't done the research yourself...it is not recommended for a reason. Not that you can't do it...just not recommended.
I was blown away by this! I just hadn't gotten around to doing any BackgroundWorkers yet...but I was blown away to find out that I shouldn't! I assumed I could always speed things up in the future by refactoring long running tasks by splitting up using parallel BackgroundWorker tasks spawned from inside the main calling method.
OK so finally to my question. Assuming I am 100% ASP.NET client for the foresee-able years...
What good (other than preparedness and education) does Async in my business layer do me? I can't or shouldn't use it right?!
I feel like I have a mill-stone around my neck called legacy Sync code just so ASP.NET can run right! Yuck!
But maybe I am missing something. Johnny was good enough to alter the CSLA.BackgroundWorker to properly handle the switch back and forth from HttpContext.Current and TLS. But you are still officially saying don't use it because it wasn't designed for that.
As I mentioned in the other thread, the new async/await keywords in .NET 4.5 will have an impact on whether to use async tasks in ASP.NET.
This is specifically because async/await does't necessarily (or automatically) create or use background threads, it just enables async operations.
Async operations can include the use of background threads, but it can also include the use of async calls to otherwise blocking IO operations. That latter scenario doesn't chew up another thread, but with async/await your primary thread doesn't have to block while the operation runs.
async/await is primarily designed for smart client scenarios, but I rather suspect it will have applicability in some ASP.NET scenarios too.
In the meantime though, your summary is pretty much spot-on - if you are building ASP.NET apps, and not building smart client apps, the cost of using async is almost always higher than any benefit you might get from using it.
Whew! Thanks, it feels good to understand the landscape...so much to know these days.
OK so one final question. Do you consider these two scenarios the same in ASP.NET.
#1 - Async call to a factory method on a business object from ASP.NET (not recommended)
#2 - Sync call to a factory method on a business object - BUT - within this business object some parallel-ism is employed so that it spins off 2 or 3 Background worker threads...the business object factory method waits for each to complete and then returns to the ASP.NET page which made the original sync call. This insulates / hides any async from the ASP.NET. The point would be to cut down the time needed since presumably child operations could be carried out in parallel instead of serially.
Anyone care to chime in with an opinion on this final question?
Once inside a call to one syncronous factory method (say execute on a command object) from my asp.net page...is it bad (inside the business layer) to employ parallel background tasks and waiting for all the background workers to finish before returning execution back to the web page
This hides the async inside the business layer and the ASP.NET page thinks it is all syncronous.
Is that ok or bad too in ASP.NET?
If your DAL is running on the web server you have the same issues with using the thread pool as any other threading scenario.
If your DAL is running on an app server, so the root data portal call transfers to the app server, and the async DAL code is running on the app server, then you've shifted the threading off the web server.
None of this is to say that you'll saturate your web server's thread pool by using async on the web server. That depends on your load, the duration of the data access operations, etc.
In other words, none of this is inherently bad - you just need to know the consequences of your choices so if bad thing happen you know why, and how to address them.
Copyright (c) Marimer LLC