ASP.NET thread agility - how to overcome? - asp.net

ASP.NET is known to exhibit what is called "thread agility". In short, it means that multiple threads may be employed to fulfill a single request, although not more than one thread at a time. This is an optimization that means a thread waiting for asynchronous I/O may be returned to the pool and used to service other requests.
However, ASP.NET does not migrate all thread-related data when moving a request. Microsoft either forgot to do so, or thought that using thread-local storage (made easy by the ThreadStatic attribute) was something only the people coding ASP.NET themselves should do.
Based on quick googling, it seems to me that the only way to avoid the issue is to rely on HttpContext instead. The context is indeed migrated if ASP.NET decides to switch threads mid-request, so this overcomes the problem. But it creates a brand new headache instead: It ties your application logic to HttpContext, and therefore to a web context. That's not acceptable in all situations (in fact, I'd say it's unacceptable in most). Besides, since HttpContext is sealed and has internal constructors, you cannot mock or stub it, and therefore your logic also becomes untestable.
According to this (old) blog post, CallContext does NOT work, which is pretty infuriating given that a call context is conceptually precisely a logical thread!
Is there a simple way to reliably implement "per-LOGICAL-thread" isolation that will work in asp.net contexts as well as other contexts?
If not, does anyone know of a lightweight third-party framework that solves the problem? Does StructureMap behave correctly when ASP.NET migrates threads?
I would like a general answer, but in case anyone wonders, the specific use case I'm looking at is for use of Entity Framework in a SharePoint context. We're unfortunately stuck with SP-2010 and EF 3.5 for a while. EF basically requires that data is saved using the same context as they were originally read from - or else you have to keep track of changes yourself. I would like to introduce a "current model" concept. The first time the model is called upon in processing each HTTP request it should be instantiated, and then that same model instance should be used for the duration of the request. But the code relying on "Model.Current" should also work if executed in the context of a timer job. I'm fine with the timer job code explicitly disposing of the model when done with it (a task I'd like to give to a handler for HttpApplication.EndRequest in the SharePoint web context).
There may be reasons not to do this, and that's interesting too, but I would anyway really appreciate to learn of a way to achieve "logical thread isolation" in an asp.net context, as it'd be remarkably useful.

There is a nice post related to the problem: Implicit Async Context ("AsyncLocal").
If I got everything right, Logical CallContext i.e. CallContext.LogicalGetData and CallContext.LogicalSetData make it real to migrate immutable data correctly given you live in the world past .NET 4.5. This immutable limitation is a nut but still...way to go.

Related

How bad is it to run an entire HTTP action method in separate thread using Task::Run()?

I'm writing web services in C++/CLI (not my choice) using Microsoft's Web API. A lot of functions in Web API are async, but because I'm using C++/CLI, I don't get the async/await support of C# or VB. So the fallback position is to use ContinueWith() to schedule a continuation delegate for reading the async task's result safely.
However, because C++/CLI also doesn't support inline anonymous delegates or managed lambdas, every delegate continuation must be written as a separate function somewhere. That quickly turns into spaghetti with the number of async functions in Web API.
So, to avoid the deadlock issues of Task<T>::Result, I've been trying this:
[HttpGet, Route( "get/some/dto" )]
Task< SomeDTO ^ > ^ MyActionMethod()
{
return Task::Run( gcnew Func< SomeDTO ^ >( this, &MyController::MyActionMethod2 ) );
}
SomeDTO ^ MyActionMethod2()
{
// execute code and use any task->Result calls I need without deadlocking
}
Okay, so I know this isn't great, but how bad is it? I don't yet understand enough of the guts of Web API or ASP.NET to comprehend the performance or scaling ramifications this will have.
Also, what other consequences may this have that aren't necessarily related to performance? For example, exceptions get wrapped in an extra AggregateException, which represents additional complexity and work for handling exceptions.
Your memory usage will increase with your application's parallelism. For every concurrent call to MyActionMethod you will need a separate thread with its own stack. That will cost you about 1 MB of RAM for each concurrent call. If MyActionMethod runs long enough so that 10000 instances run at once, you're looking at 10 GB of RAM. There is also CPU overhead in setting up each thread.
If concurrency is low, dropping async support won't be a problem. In that case, don't bother with Task::Run. Just change MyActionMethod to return SomeDTO^ (no Task wrapper).
Another potential concern is that lose easy use of cancellation tokens. However, for Web API it's usually fine to just let an exception propagate back to Web API, which ends up cancelling the synchronous call anyway.
Finally, if you were planning on performing any operation within your action method in parallel, you'll still need to use ContinueWith to accomplish that. Going non-async by default means you'll always perform one operation at a time. Fortunately, it's often just fine to do so.
Okay, so I know this isn't great, but how bad is it?
It's difficult to answer this without load-testing your specific scenario. But you can walk through the known semantics (taken largely from my blog).
First, when a request comes in, ASP.NET executes your handler on a thread pool thread within that request context. Your request handler calls Task.Run, which takes another thread from the thread pool and executes the actual request logic on it. The handler then returns the task returned from Task.Run; this releases the original request thread back to the thread pool.
Then, the Task.Run delegate will block on any asynchronous parts. So, this pattern has the scaling disadvantages of a regular synchronous handler, plus an extra thread context switch. Also, it uses a thread from the ASP.NET thread pool, which is not necessarily a bad thing, but in some scenarios it may throw off the ASP.NET thread pool heuristics.
Also, what other consequences may this have that aren't necessarily related to performance? For example, exceptions get wrapped in an extra AggregateException, which represents additional complexity and work for handling exceptions.
Yes, the exceptions from any .Result or Wait() calls will be wrapped in AggregateException. You may be able to avoid this by calling .GetAwaiter().GetResult() instead.
Another important consideration is that the code executing within the Task.Run is executing without a request context. So, ambient data like HttpContext.Current, current culture, thread principal, etc. are not going to be set correctly. You'll have to capture any important data before calling Task.Run and pass it down manually.

NHibernate, Sqlite, missing tables and IOC fun

I'm doing unit testing on a class library that uses NHibernate for persistence. NHibernate is using a Sqlite in-memory database for testing purposes. Under normal circumstances, it's easy to get StructureMap to kick out a session for me.
However, because I'm using the in-memory database to improve testing speed, I need to have a single session available for the duration of a test (because it blows the database away when I create a new one). And there is another wrinkle. The case that is currently burning me is testing a custom NHibernate-based ASP.NET membership provider. These are created apparently once per AppDomain, so I shouldn't inject the session into it, for obvious reasons.
Is there a way in structuremap to tell it to get rid of an instance of a particular type while still maintaining the bits that tell it how to instantiate that type? Really, if I could get away with it, I would just make it act like the HttpScoped object lifetime, but apparently I can only do that within the context of an Http request. Is there a straightforward way to manually control the lifetime of an object coming out of structuremap?
I apologize for the length of this and the possibility that it is a dumb question. I'm solo on this project, so I don't really have anyone to bounce ideas off of.
You could wrap the session in your own ISession implementation which delegates to a real session which lifetime you control. Then register your own ISession as instance.
I ended up making two constructors for my provider along with a private variable of type Func. By default, its value was set to my standard code for creating a session using StructureMap's ObjectFactory.
The overloaded constructor accepted as a parameter an object of type Func. That way, I can inject a strategy for creating an instance of that type if needed, but otherwise don't have to go through any extended effort. In the case of my test, I created the session in the NUnit setup method and destroyed it in the Teardown. I don't love this idea, but I don't currently hate it enough to rip it out....yet.
This got rid of the error I was experiencing in regard to the tables. However, it appears that NHibernate for some reason cannot write to an in-memory sqlite database under the conditions I created. I'm now working on testing to see if I can write to one in the file system. It isn't ideal, but it will be a good long while (I hope), before the performance of writing to disk really starts hurting.

IHttpAsyncHandler causes UnathorizedAccessException

For the last couple of days of my X-mas holidays, I have been struggling with an UnathorizedAccessException when trying to READ a XML file on a remote share through my ASP.NET application using an implementation of the IHttpAsyncHandler a long with the IRequiresSessionState.
After much headache, and concluding that the code OUTSIDE the handler worked flawlessly (see: access granted), I thought it might be some threading issue, so I changed the IHttpAsyncHandler to IHttpHandler, and the problem disappears.
What is troubling me here is, that for test purposes, I did not actually make use if the IHttpAsyncHandler implementation (hence, I did not use BeginProcessRequest and EndProcessRequest - only the sync. version, ProcessRequest.
Can anyone try to explain the issue at hand?
There are some beneficial matters in using the handler asynchronously, as I could pre-cache the values to be delivered later in the application, but for that to work, I have to get pass the security issues that seems to only manifest when implementing the IHttpAsyncHandler.
Thanks in advance for your kind help - and happy holidays :-)
The ASP.NET infrastructure calls an async handler differently (regardless if the impl is truly async). Is it possible that you were relying on impersonation to access the network resource? My guess would be that the necessary WindowsIdentity didn't flow to the threadpool thread that actually handled the request (I've never tried using impersonation + async handler, but I've gotten nailed with other thread state flow issues in the past).
Regardless, a true async handler is expensive to implement correctly. Unless you're building on top of a lot of other async infrastructure (async file i/o, async DB client, etc), it doesn't do you any good (in fact, even in the best cases, async handlers hurt raw performance). I'd look to see if your performance needs really justify the extra hassle and overhead of an async handler (eg, you need to service many more concurrent requests than threads in the process, etc).

What should I be aware of when threading in ASP.NET?

Recently, the book on threading for Winforms application (Concurrent programming on Windows by Joe Duffy) was released. This book, focused on winforms, is 1000 pages.
What gotchas are there in ASP.NET threading? I'm sure there are plenty of gotchas to be aware of when implementing threading in ASP.NET. What should I be aware of?
Thanks
Since each http request received by IIS is processed separately, on it's own thread anyway, the only issues you should have is if you kick off some long running process from within the scope of a single http request. In that case, I would put such code into a separate referenced dependant assembly, coded like a middle-tier component, with no dependance or coupling to the ASP.Net model at all, and handle whatever concurrency issues arose within that assembly separately, without worrying about the ASP.Net model at all...
Jeff Richter over at Wintellect has a library called PowerThreading. It is very useful if you are developing applications on .NET. => Power Threading Library
Check for his presentations online at various events.
Usually you are encouraged to use the thread pool in .Net because it of the many benefits of having things managed on your behalf.....but NOT in ASP.net.
Since ASP.net is already multi-threaded, it uses the thread pool to serve requests that are mapped to the ASP.net ISAPI filter, and since the thread pool is fixed in size, by using it you are basically taking threads away that are set aside to do the job of handling request.
In small, low-traffic websites, this is not an issue, but in larger, high-traffic websites you end up competing for and consuming threads that the ASP.net process relies on.
If you want to use threading, it is fine to do something like....
Thread thread = new Thread(threadStarter);
thread.IsBackground = true;
thread.Start();
but with a warning: be sure that the IsBackground is set to true because if it isn't the thread exists in the foreground and will likely prevent the IIS worker process from recycling or restarting.
First, are you talking about asynchronous ASP.NET? Or using the ThreadPool/spinning up your own threads?
If you aren't talking about asynchronous ASP.NET, the main question to answer is: what work would you be doing in the other threads and would the work be specific to a request/response cycle, or is it more about processing global tasks in the background?
EDIT
If you need to handle concurrent operations (a better term than multi-threaded IMO) for a given request/response cycle, then use the asynchronous features of ASP.NET. These provide an abstraction over IIS's support for concurrency, allowing the server to process other requests while the current request is waiting for work to complete.
For background processing of global tasks, I would not use ASP.NET at all. You should assume that IIS will recycle your AppPool at a random point in time. You also should not assume that IIS will run your AppPool on any sort of schedule. Any important background processing should be done outside of IIS, either as a scheduled task or a Windows Service. The approach I usually take is to have a Windows Service and a shared work-queue where the web-site can post work items. The queue can be a database table, a reliable message-based queue (MSMQ, etc), files on the file system, etc.
The immediate thing that comes to mind is, why would you "implement threading" in ASP.NET.
You do need to be conscious all the time that ASP.NET is multi-threaded since many requests can be processed simulatenously each in its own thread. So for example use of static fields needs to take threading into account.
However its rare that you would want to spin up a new thread in code yourself.
As far as the usual winforms issues with threading in the UI is concerned these issues are not present in ASP.NET. There is no window based message pump to worry about.
It is possible to create asynchronous pages in ASP.NET. These will perform all steps up to a certain point. These steps will include asynchronously fetching data, for instance. When all the asynchronous tasks have completed, the remainder of the page lifecycle will execute. In the meantime, a worker thread was not tied up waiting for database I/O to complete.
In this model, all extra threads are executing while the request, and the page instance, and all the controls, still exist. You have to be careful when starting your own threads, that, by the time the thread executes, it's possible that the request, page instance, and controls will have been Disposed.
Also, as usual, be certain that multiple threads will actually improve performance. Often, additional threads will make things worse.
The gotchas are pretty much the same as in any multithreaded application.
The classes involved in processing a request (Page, Controls, HttpContext.Current, ...) are specific to that request so don't need any special handling.
Similarly for any classes you instantiate as local variables or fields within these classes, and for access to Session.
But, as usual, you need to synchronize access to shared resources such as:
Static (C#) / Shared(VB.NET) references.
Singletons
External resources such as the file system
... etc...
I've seen threading bugs too often in ASP.NET apps, e.g. a singleton being used by multiple concurrent requests without synchronization, resulting in user A seeing user B's data.

Silverlight,asynchronous,lazy loading what's the best way?

I started to use silverlight/flex and immediately bumped into the asynchronous service calling. I'm used to solving the data access problems in an OO-way with one server fetch mechanism or another.
I have the following trivial code example:
public double ComputeOrderTotal(Order order)
{
double total = 0;
// OrderLines are lazy loaded
foreach (Orderline line in order.Orderlines)
{
// Article,customer are lazy loaded
total = total + line.Article.Price - order.Customer.discount;
}
return total;
}
If I understand correctly, this code is impossible in Flex/Silverlight. The lazy loading forces you to work with callbacks. IMO the simple expample above will be a BIG mess.
Can anyone give me a structured way to implement the above ?
Edit:
The problem is the same for Flex/Silverlight, pseudo code would
do fine
Its not really ORM related but most orms use lazy loading so i'll remove
that tag
The problem is lazy loading in the model
The above example would be very doable of all data was in memory but
we assume some has to be fetched from
the server
Closueres dont help since sometimes data is already loaded and no asynchronous fetch is needed
Yes I must agree that O/R mapping is usually done on the server-side of your application.
In SilverLight asynchronous way of execution is the desired pattern to use when working with services. Why services? Because as I said before there is no O/R mapping tool at the moment that could be used on the client-side (SilverLight). The best approach is to have your O/R mapped data exposed by a service that can be consumed by a SilverLight application. The best way at the moment is to use Ado.Net DataServices to transport the data, and on the client-side to manage the data using LINQ to Services. What is really interesting about ADS (former Astoria project) is that it is designed to be used with Entity Framework, but the good folks also implemented support for IQueriable so basically you can hook up any data provider that support LINQ. To name few you can consider Linq To Sql, Telerik OpenAccess, LLBLGen, etc. To push the updates back to the server the data source is required to support the ADS IUpdateable.
You can look just exactly how this could be done in a series of blogposts that I have prepared here: Getting Started with ADO.NET Data Services and Telerik Open Access
I can't speak to Silverlight but Flex is a web browser client technology and does not have any database driver embedded in the Flash runtime. You can do HTTP protocol interactions to a web server instead. It is there in the middle-tier web server where you will do any ORM with respect to a database connection, such as Java JDBC. Hibernate ORM and iBATIS are two popular choices in the Java middle-tier space.
Also, because of this:
Fallacies of Distributed Computing
You do not do synchronous interactions from a Flex client to its middle-tier services. Synchronous network operations have become verboten these days and are the hallmark signature of a poorly designed application - as due to reasons enumerated at the above link, the app can (and often will) exhibit a very bad user experience.
You instead make async calls to retrieve data, load the data into your client app's model object(s), and proceed to implement operations on the model. With Flex and BlazeDS you can also have the middle-tier push data to the client and update the client's model objects asynchronously. (Data binding is one way to respond to data being updated in an event driven manner.)
All this probably seems very far afield from the nature of inquiry in your posting - but your posting indicates you're off on an entirely incorrect footing as to how to understand client-side technologies that have asynchronous and event-driven programming baked into their fundamental architecture. These RIA client technologies are designed this way completely on purpose. So you will need to learn their mode of thinking if you want to have a good and productive experience using them.
I go into this in more detail, and with a Flex perspective, in this article:
Flex Async I/O vs Java and C# Explicit Threading
In my direct experience with Flex, I think this discussion is getting too complicated.
Your conceptual OO view is no different between sync and asynch. The only difference is that you use event handlers to deal with the host conversation in the DAL, rather than something returned from a method call. And that often happens entirely on the host side, and has nothing to do with Flex or Silverlight. (If you are using AIR for a workstation app, then it might be in client code, but the same applies. As well if you are using prolonged AJAX. Silverlight, of course, has no AIR equivalent.)
I've been able to design everything I need without any other changes required to accomodate asynch.
Flex has a single-threaded model. If you make a synchronous call to the web server, you'd block the entire GUI of the application. The user would have a frozen application until the call completes (or times out on a network error condition, etc.).
Of course real RIA programs aren't written that way. Their GUI remains accessible and responsive to the user via use of async calls. It also makes it possible to have real progress indicators that offer cancel buttons and such if the nature of the interaction warrants such.
Old, bad user experience web 1.0 applications exhibited the synchronous behaviour in their interactions with the web tier.
As my linked article points out, the async single-threaded model coupled with ActionScript3 closures is a good thing because it's a much simpler programming model than the alternative - writing multi-thread apps. Multi-threading was the approach of writing client-server Java Swing or C# .NET WinForm applications in order to achieve a similarly responsive, fluid-at-all-times user experience in the GUI.
Here's another article that delves into this whole subject matter of asynchronous, messaging/event-driven distributed app architecture:
Building Effective Enterprise Distributed Software Systems
data-driven communication vs behavior-driven communication
Silverlight is a client technology and the Object - Relational mapping happens completely in the server. So you have to forgot about the ORM in Silverlight.
Following your example what you have to do is to create a webservice (SOAP, REST...) that can give your silverlight client the complete "Order" object.
Once you have the object you can work with it with no communication with the server in a normal - synchronous way.
Speaking about Silverlight, you should definitely check RIA services.
Simply, it brings the DataContext from the server to the client from where you can asynchronously query it (there is no need to write WCF services by hand, it's all done by RIA).
C# 5
async / await construct will almost exactly what I want..
watch presentation by anders hejlsberg

Resources