Last post Oct 26, 2011 04:47 PM by desertfoxaz
Dec 20, 2010 05:03 PM|desertfoxaz|LINK
I have an application that uses an asynchronous HttpHandler to retrieve images and display them on a page by having the asp:Image tag's ImageUrl property set to the handler's URL and some additional querystring arguments. Getting the images is a somewhat
complicated process (it applies autocorrections to images based on pre-defined settings). Is an asynchronous handler the right choice for this?
Also, it seems that the page, which four of these images, seems to load them sequentially instead of in parallel. As there is a bit of a delay to get each image in the first place, the total wait time to get all four images is a bit longer than we'd like. I
was thinking that the browser (IE8) should be able to download multiple images simulaneously (they are not that big either) but from my anaylsis this isn't the case. Image 2 doesn't begin downloading until image 1 is done downloading, etc. Therefore this
doesn't seem very asynchronous. I am new to asynchronous programming though so maybe I'm missing something. Also, would switching the IsReusable property from false to true make much of a difference? The handler itself isn't doing anything more than just
calling a web method and passing back the results.
Assuming I cannot change how the images are actually retrieved (they coming back as byte arrays from a ASMX web service - yeah, I know that's inefficient but we're stuck with it for the time being), is there anything I can do in the handler or in the configuration
of the application or server that could speed things up? This is a .NET 3.5 application. What about tweaking the web service methods so they're more efficient?
Dec 22, 2010 07:48 AM|Saravanan M|LINK
Have a look at this forum
Dec 22, 2010 10:06 PM|rstrahl|LINK
Browsers use multiple threads to load content but the number is fairly limited. If you have a slow process that downloads images it could quickly tie up the connections that the browser has available. A simple way to check this is to try use FireFox and
tweak the simultaneous Http connections in about:config. If this works better then you know the problem is the browser not your app (which I would suspect).
One thing to understand about server side Async loading is that it doesn't help with request time. All it does provide is freeing up of ASP.NET threads to process more requests in its allocated IO thread pool as processing is offloaded from the ASP.NET thread
to a system thread. When the processing is done the ASP.NET an ASP.NET IO thread is then re-attached and the request is returned to the browser. This doesn't make the processing any faster however so as far as the client is concerned there's no discernable
In general Async processing is useful only in IO bound operations (like calling a Web Service or waiting on a long SQL statement) that don't push the CPU much or offload processing to another machine, but it rarely helps request speed or reducing load
on the server.
Ultimately I think your issue is that images load slowly so your primary concern most likely should be to provide caching or some sort of pre-processing so that the load time is reduced when the request for a given image comes in...
Probably not what you wanted to hear :-) but I hope it gives you some ideas on what to look at next.
+++ Rick ---
Dec 23, 2010 11:36 AM|desertfoxaz|LINK
The problem I'm having in the application is scalability. I suspect that because I have a lot of long-running prcoesses that may be blocking threads. The system works pretty good with a limited number of users but once we get past a few dozen it slows
down considerably. We've already thrown extra hardware at the problem but that is expensive and only provides a minimal increase in performance.
My boss wants me to try to correct this but the application in question is a mess and I don't dare try modifying it without having a good understanding of how asynchronous programming works. Therefore, what I was trying to do is to create a scaled-down
proof-of-concept that uses both asynchronous HttpHandlers that call asynchronous WebServices in an effort to simulate getting these images (which they've identified is the bottleneck).
I've found some good articles but I can't quite get my POC working based on the principles detailed in these articles.
(Why is it that whenever someone posts their code online, it never builds?)
I don't even know where to go on this one. I've worked on this application for three years and done just about everything I can think of to make it faster, but I'm at the mercy of the original architecture and rewriting this application is not an option
at this point because we're starting a year-long re-architecture and they want this app working better now as they can't wait for the new system to be available.
Oct 26, 2011 04:47 PM|desertfoxaz|LINK
From what I've read, the current implementation of the Asynchronous handler isn't being done right. Basically, it's swapping one IIS thread with another, instead of using an OS thread. Therefore, this handler is behaving like a synchronous handler. However,
that isn't necessarily a bad thing because synchronous handlers (those implementing IHttpHandler) can be called in parallel by the browser so you don't necessarily gain much by making it truly asynchronous. In this case, it was only retrieving images and
that isn't a particularly long-running process.
My handlers need to access session state. This is required because I don't want to allow users to manipulate the URL querystring which could potentially allow someone to get access to data they should be able to get to. Session state is by default not
available in handlers, but you can enable it by implementing IRequiresSessionState. Session is then available throught he context argument passed into the ProcessRequest method. However, if you plan on calling the handlers more than once in a particular
page there is a problem with this. Apparently, the .NET runtime thinks that writing to session is not thread-safe. Thefore, by implementing this interface, it restricts access to the handler to one thread at a time meaning the requests cannot be done in
parallel. Fortunately, I am not writing to session, I am only reading from it. In this case, you should implement IReadOnlySessionState (which also implements IRequiresSessionState, so don't implement both). This will remove the restriction and allow as
many requests to be processed up to the limit imposed by IIS. In the case where I am using the handlers to display multiple images in the page, they can now execute in parallel instead of in sequence. My application was getting four images so this change
gave me a 75% improvement in execution time, assuming that all requests take the same amount of time to execute. Unfortunately the MSDN documentation doesn't state anything about this and I had to Google it.