Using Task or async/await in IHttpAsyncHandler - asp.net

Since the very begining of writing ASP.NET applications when I wanted to add a threading there are 3 simple ways I can accomplish threading within my ASP.NET application :
Using the System.Threading.ThreadPool.
Using a custom delegate and calling its BeginInvoke method.
Using custom threads with the aid of System.Threading.Thread class.
The first two methods offer a quick way to fire off worker threads for your application. But unfortunately, they hurt the overall performance of your application since they consume threads from the same pool used by ASP.NET to handle HTTP requests.
Then I wanted to use a new Task or async/await to write IHttpAsyncHandler. One example you can find is what Drew Marsh explains here : https://stackoverflow.com/a/6389323/261950
My guess is that using Task or async/await still consume the thread from the ASP.NET thread pool and I don't want for the obvious reason.
Could you please tell me if I can use Task (async/await) on the background thread like with System.Threading.Thread class and not from thread pool ?
Thanks in advance for your help.
Thomas

This situation is where Task, async, and await really shine. Here's the same example, refactored to take full advantage of async (it also uses some helper classes from my AsyncEx library to clean up the mapping code):
// First, a base class that takes care of the Task -> IAsyncResult mapping.
// In .NET 4.5, you would use HttpTaskAsyncHandler instead.
public abstract class HttpAsyncHandlerBase : IHttpAsyncHandler
{
public abstract Task ProcessRequestAsync(HttpContext context);
IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
var task = ProcessRequestAsync(context);
return Nito.AsyncEx.AsyncFactory.ToBegin(task, cb, extraData);
}
void EndProcessRequest(IAsyncResult result)
{
Nito.AsyncEx.AsyncFactory.ToEnd(result);
}
void ProcessRequest(HttpContext context)
{
EndProcessRequest(BeginProcessRequest(context, null, null));
}
public virtual bool IsReusable
{
get { return true; }
}
}
// Now, our (async) Task implementation
public class MyAsyncHandler : HttpAsyncHandlerBase
{
public override async Task ProcessRequestAsync(HttpContext context)
{
using (var webClient = new WebClient())
{
var data = await webClient.DownloadDataTaskAsync("http://my resource");
context.Response.ContentType = "text/xml";
context.Response.OutputStream.Write(data, 0, data.Length);
}
}
}
(As noted in the code, .NET 4.5 has a HttpTaskAsyncHandler which is similar to our HttpAsyncHandlerBase above).
The really cool thing about async is that it doesn't take any threads while doing the background operation:
An ASP.NET request thread kicks off the request, and it starts downloading using the WebClient.
While the download is going, the await actually returns out of the async method, leaving the request thread. That request thread is returned back to the thread pool - leaving 0 (zero) threads servicing this request.
When the download completes, the async method is resumed on a request thread. That request thread is briefly used just to write the actual response.
This is the optimal threading solution (since a request thread is required to write the response).
The original example also uses threads optimally - as far as the threading goes, it's the same as the async-based code. But IMO the async code is easier to read.
If you want to know more about async, I have an intro post on my blog.

I've been looking for information through internet for a couple of days. Let me sum up what I found until now :
ASP.NET ThreadPool facts
As Andres said: When async/await will not consume an additional ThreadPool thread ? Only in the case you are using BCL Async methods. that uses an IOCP thread to execute the IO bound operation.
Andres continues with ...If you are trying to async execute some sync code or your own library code, that code will probably use an additional ThreadPool thread unless you explicitely use the IOCP ThreadPool or your own ThreadPool.
But as far as I know you can't chose whetever you want to use a IOCP thread, and making correct implementation of the threadPool is not worth the effort. I doubt someone does a better one that already exists.
ASP.NET uses threads from a common language runtime (CLR) thread pool to process requests. As long as there are threads available in the thread pool, ASP.NET has no trouble dispatching incoming requests.
Async delegates use the threads from ThreadPool.
When you should start thinking about implementing asynchronous execution ?
When your application performs relatively lengthy I/O operations (database queries, Web service calls, and other I/O operations)
If you want to do I/O work, then you should be using an I/O thread (I/O Completion Port) and specifically you should be using the async callbacks supported by whatever library class you're using. Theirs names start with the words Begin and End.
If requests are computationally cheap to process, then parallelism is probably an unnecessary overhead.
If the incoming request rate is high, then adding more parallelism will likely yield few benefits and could actually decrease performance, since the incoming rate of work may be high enough to keep the CPUs busy.
Should I create new Threads ?
Avoid creating new threads like you would avoid the plague.
If you are actually queuing enough work items to prevent ASP.NET from processing further requests, then you should be starving the thread pool! If you are running literally hundreds of CPU-intensive operations at the same time, what good would it do to have another worker thread to serve an ASP.NET request, when the machine is already overloaded.
And the TPL ?
TPL can adapt to use available resources within a process. If the server is already loaded, the TPL can use as little as one worker and make forward progress. If the server is mostly free, they can grow to use as many workers as the ThreadPool can spare.
Tasks use threadpool threads to execute.
References
http://msdn.microsoft.com/en-us/magazine/cc163463.aspx
http://blogs.msdn.com/b/pfxteam/archive/2010/02/08/9960003.aspx
https://stackoverflow.com/a/2642789/261950

Saying that "0 (zero) threads will be servicing this request" is not accurate entirely.
I think you mean "from the ASP.NET ThreadPool", and in the general case that will be correct.
When async/await will not consume an additional ThreadPool thread?
Only in the case you are using BCL Async methods (like the ones provided by WebClient async extensions) that uses an IOCP thread to execute the IO bound operation.
If you are trying to async execute some sync code or your own library code, that code will probably use an additional ThreadPool thread unless you explicitely use the IOCP ThreadPool or your own ThreadPool.
Thanks,
Andrés.

The Parallel Extensions team has a blog post on using TPL with ASP.NET that explains how TPL and PLINQ use the ASP.NET ThreadPool. The post even has a decision chart to help you pick the right approach.
In short, PLINQ uses one worker thread per core from the threadpool for the entire execution of the query, which can lead to problems if you have high traffic.
The Task and Parallel methods on the other hand will adapt to the process's resources and can use as little as one thread for processing.
As far as the Async CTP is concerned, there is little conceptual difference between the async/await construct and using Tasks directly. The compiler uses some magic to convert awaits to Tasks and Continuations behind the scenes. The big difference is that your code is much MUCH cleaner and easier to debug.

Another thing to consider is that async/await and TPL (Task) are not the same thing.
Please read this excellent post http://blogs.msdn.com/b/ericlippert/archive/2010/11/04/asynchrony-in-c-5-0-part-four-it-s-not-magic.aspx to understand why async/await doesn't mean "using a background thread".
Going back to our topic here, in your particular case where you want to perform some expensive calculations inside an AsyncHandler you have three choices:
1) leave the code inside the Asynchandler so the expensive calculation will use the current thread from the ThreadPool.
2) run the expensive calculation code in another ThreadPool thread by using Task.Run or a Delegate
3) Run the expensive calculation code in another thread from your custom thread pool (or IOCP threadPool).
The second case MIGHT be enough for you depending on how long your "calculation" process run and how much load you have. The safe option is #3 but a lot more expensive in coding/testing. I also recommend always using .NET 4 for production systems using async design because there are some hard limits in .NET 3.5.

There's a nice implementation of HttpTaskAsyncHandler for the .NET 4.0 in the SignalR project. You may want to ckeck it out: http://bit.ly/Jfy2s9

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.

Asp.net SynchronizationContext locks HttpApplication for async continuations?

This comment by Stephen Cleary says this:
AspNetSynchronizationContext is the strangest implementation. It treats Post as synchronous rather than asynchronous and uses a lock to execute its delegates one at a time.
Similarly, the article that he wrote on synchronization contexts and linked to in that comment suggests:
Conceptually, the context of AspNetSynchronizationContext is complex. During the lifetime of an asynchronous page, the context starts with just one thread from the ASP.NET thread pool. After the asynchronous requests have started, the context doesn’t include any threads. As the asynchronous requests complete, the thread pool threads executing their completion routines enter the context. These may be the same threads that initiated the requests but more likely would be whatever threads happen to be free at the time the operations complete.
If multiple operations complete at once for the same application, AspNetSynchronizationContext will ensure that they execute one at a time. They may execute on any thread, but that thread will have the identity and culture of the original page.
Digging in reflector seems to validate this as it takes a lock on the HttpApplication while invoking any callback.
Locking the app object seems like scary stuff. So my first question: Does that mean that today, all asynchronous completions for the entire app execute one at a time, even ones that originated from separate requests on separate threads with separate HttpContexts? Wouldn't this be a huge bottleneck for any apps that make 100% use of async pages (or async controllers in MVC)? If not, why not? What am I missing?
Also, in .NET 4.5, it looks like there's a new AspNetSynchronizationContext, and the old one is renamed LegacyAspNetSynchronizationContext and only used if the new app setting UseTaskFriendlySynchronizationContext is not set. So question #2: Does the new implementation change this behavior? Otherwise, I imagine with the new async/await support marshaling completions through the synchronization context, this kind of bottleneck would be noticed much more frequently going forward.
The answer to this forum post (linked from SO answer here) suggests that something fundamentally changed here, but I want to be clear on what that is and what behaviors have improved, since we have a .NET 4 MVC 3 app which is pretty much 100% async action methods making web service calls.
Let me answer your first question. In your assumption you didn't consider the fact that separate ASP.NET requests are processed by different HttpApplication objects. HttpApplication objects are stored in pool. Once you request a page, an application object is retrieved from pool and belongs to the request till its completion. So, my answer to your question:
all asynchronous completions for the entire app execute one at a time, even ones that originated from separate requests on separate threads with separate HttpContexts
is: No, they don't
Separate requests are processed by separate HttpApplication objects, locked HttpApplication will affect only single request.
Synchronization context is a powerful thing that helps developers to synchronize access to shared (in scope of request) resources. That is why all callbacks are executed under lock. Synchronization context is a heart of event-based synchronization pattern.

ASP.NET MVC Multithreading

I want to implement such logic in my asp-net-mvc application:
user clicks a button ->
server executes some time-consuming logic in ~15 threads (i get data from really slow independent sources) ->
when all work is done, server merges the results and passes it back to user
The other day i've seen an article which explained why creating new Threads in asp-net application is highly not recommended, and ThreadPool is the one that should be used.
What are best practices for mvc in this case? Why shouldnt i create my threads, backgroundworkers, tasks, whatever by myself and use threadpool? The Application will be hosted on a public server, if it matters.
This seems like a really good place for using the new AsycController in ASP.NET MVC 2. It is really easy to use and lets you run queries against multiple independent sources without blocking request threads.
MSDN has a great example where they are querying a news service, a weather service, and a sports service.
You can see in the original code that they are querying each source sequentially, but in the final version, all the tasks run in parallel and control returns to the controller when they are all completed:
public void IndexAsync(string city)
{
AsyncManager.OutstandingOperations.Increment(3);
NewsService newsService = new NewsService();
newsService.GetHeadlinesCompleted += (sender, e) =>
{
AsyncManager.Parameters["headlines"] = e.Value;
AsyncManager.OutstandingOperations.Decrement();
};
newsService.GetHeadlinesAsync();
SportsService sportsService = new SportsService();
sportsService.GetScoresCompleted += (sender, e) =>
{
AsyncManager.Parameters["scores"] = e.Value;
AsyncManager.OutstandingOperations.Decrement();
};
sportsService.GetScoresAsync();
WeatherService weatherService = new WeatherService();
weatherService.GetForecastCompleted += (sender, e) =>
{
AsyncManager.Parameters["forecast"] = e.Value;
AsyncManager.OutstandingOperations.Decrement();
};
weatherService.GetForecastAsync();
}
public ActionResult IndexCompleted(string[] headlines, string[] scores, string[] forecast)
{
return View("Common", new PortalViewModel {
NewsHeadlines = headlines,
SportsScores = scores,
Weather = forecast
});
}
Yes JQuery and some AJAX will do it most properly.
Load the Page, then send ~15 separate Ajax queries back to the Server and let them finish asynchronously. This way you can let the web-server handle Threading (which is does well) and concentrate on displaying either a ticker or a virtual progress bar to the user while waiting.
If you're using .Net 4, I would even recommend looking at the parallel namespaces. They make this even simpler and do a better job of utilizing all your CPU cores.
I would also look at offloading this from your main web app altogether. Having a separate set of services or a message queue to handle this long running request will let you scale a lot more easily and will allow your web app to worry about servicing page requests, not performing long running logic. Google up something like "iis long running request" to get started.
Because a ThreadPool is designed to do that:
It provides a pool of threads that can be used to execute tasks, post work items, process asynchronous I/O, wait on behalf of other threads, and process timers.
I guess it's better to store the results on your server in a database when they are done.
And then you could use a timer and AJAX to periodically request if the process is done, if so, get data.
You shouldn't create your own threads because this has significant overhead. Creating a new thread is expensive. So the question should be: why shouldn't you use the threadpool? It has a number of threads ready for use. An even better approach would be to use the task parallel library, it provides a layer of abstraction above the threadpool that makes it a lot easier to work with threads.
You should realize that the only (easy) way to accomplish this, is by having the user wait until all work is done and then serve the page. A more complicated but also more responsive approach would be to use Ajax (via jQuery for example) to ask the server periodically how far the work has progressed. This way you can also provide some progress indicator.

asynchronous calls in asp.net

in this sample, two threads created; a worker thread created by BeginInvoke and an I/O completion thread created by SendAsync method.
but another author in his UnsafeQueueNativeOverlapped example, don't recommend this.
i want to use SendAsync or ...Async in an asp.net page and i want to use PageAsyncTask.
however, its BeginEventHandler requires AsyncResult to be returned which SendAsync does not return.
afaik, event based async pattern is the most recommended way so how could we call SendAsync or any ...Async methods without creating two threads and hurting the performance?
Actually if you used the beginIvoke and endInvoke for delegates or ThreadPool.WorkerItem it will not make any difference in your application because they are using the same thread that asp.net uses throw the iis
so now you have only 2 solution to make async calls first u will write your own threading classes (but be careful )
second use the PageAsyncTasks(recommended) this one much more safe and it's designed to work perfectly with asp.net
it's not about hurting the performance as much as it's about how and when to use asnyc tasks
if your process really take much time until it finish (because IIS will wait until all processes finish even the asnyc ones then start rendering) then you have to go to async solution instead it will make a draw back in performance
Note:
there is a difference between AddOnPreRenderCompleteAsync and RegisterAsyncTask
in there implementation they look the same but in the second one
you have access to the current http
context ,impersonation, culture and
profile data etc
you can run many tasks in parallel
you have timeout event and you can
determine timeout in the page
attribute
you can call RegisterAsyncTask
several times in one request to
register several async operations

Would ManualResetEvent/AutoResetEvent use workerthread or IO-thread in asp.net

the web layer is coded in asp.net with pages marked as async. Yes, the recommended way to code for aync is using the RegisterAsyncTask
I have a problem now - there are a few pages that have used AutoResetEvent and ManualResetEvent for aync and not the standard RegisterAsyncTask.
Would these objects servicing the async calls, use up the worker threads from the threadpool? (not recommended, as this would exhaust the worker threads and the server would not be able to serve other client requests
OR
would they use the IO threads? (typically IO threads are used for async calls with the RegsterAsyncTask, this is desired)
I would need to propose change to these pages based on your insights.
Any opinions please?
The reset event objects don't use different threads themselves - they just block/release the current thread based on the current state and the activities of other threads.
When you say there are other pages "that have used AutoResetEvent and ManualResetEvent for a[s]ync" what exactly do you mean? These are synchronization objects, and don't provide a way (in themselves) of making operations asynchronous. Something else must be starting a thread or using the thread pool.

Resources