Sunday, October 21, 2012

Ultra fast ASP.NET

1. A good rule of thumb is to load your static content from two or three domains. You might want to have several domain aliases for your site. That allows you to optimize download parallelism by simply adjusting the domain names in your pages, without having to manage which content is in which domain. Consider automating the process of assigning static files to particular domains using an ASP.NET control adapter just be sure to use a consistent domain for each resource, to avoid unwanted cache misses.

2. To reduce round-trips, you should have as few script files as possible. You can arrange this by doing one or more of the following:
  • Combine them together statically (such as with an editor)
  • Combine them together dynamically, either:
    • As a compile post-processing step or
    • Programmatically (on-demand) when the browser requests the script. The .NET Framework supports automated bundling.
3. Mid-document script includes can cause the browser to delay rendering the page until after the script file arrives. From a performance perspective, it’s better to place your includes at the end of your HTML when you can. A common reason for using mid-document script includes is to insert HTML into the page using document.write().
  • Instead of document.write(), use innerHTML or direct DOM manipulation, which you can do late in the HTML
  • If you can’t avoid document.write() (such as with scripts from third-parties), then instead of using multiple

Should web services be called asynchronously from ASP.NET page?

What if you have a thread that makes an HTTP or SOAP request to another server and takes a long time, should you switch threads?

Yes! You can perform the HTTP or SOAP request asynchronously, so that once the "send" has occurred, you can unwind the current thread and not use any threads until there is an I/O completion for the "receive". Between the "send" and the "receive", the remote server is busy, so locally you don't need to be blocking on a thread, but instead make use of the asynchronous APIs provided in .NET Framework so that you can unwind and be notified upon completion.  Again, it only makes sense to switch threads if the benefit from doing so out weights the cost of the switch.

However, just calling web service asynchronously does not help?

If you want work to be performed asynchronously—truly asynchronously, as in the current thread unwinds and execution of the request resumes only if and when your work completes—then you must run inside a module or handler that is asynchronous. If you do not use an asynchronous handler, the thread that ASP.NET initiated to handle incoming request will have to be blocked. So, even though you call web service asynchronously it really would not help in a true sense.

How many concurrent requests can ASP.NET handle?

Following are settings that effect the number of requests that ASP.NET can handle at a time. And when we mean requests, it is incoming requests that has been placed by IIS in the CLR threadpool.
Configuration settingDefault value (.NET Framework 1.1)Recommended value
maxconnection212 * #CPUs
maxIoThreads20100
maxWorkerThreads20100
minFreeThreads888 * #CPUs
minLocalRequestFreeThreads 476 * #CPUs
So,

Number of requests that ASP.NET runtime can handle = Number of worker threads available to handle incoming requests = maxWorkerThreads - minFreeThreads = 100 - 88 = 12

The recommendation to limit the ASP.NET runtime to 12 threads for handling incoming requests is most applicable for quick-running operations. The limit also reduces the number of context switches. If your application makes long-running calls, first consider the design alternatives. If the alternative designs cannot be applied in your scenario, start with 100 maxWorkerThreads, and keep the defaults for minFreeThreads. This ensures that requests are not serialized in this particular scenario.

The idea is always to reduce contention. Performance counters to watch out for are

  • CPU utilization increases.
  • Throughput increases according to the ASP.NET Applications\Requests/Sec performance counter.
  • Requests in the application queue decrease according to the ASP.NET Applications/Requests In Application Queue performance counter.

Sunday, October 14, 2012

HTTP Pipeline in ASP.NET



1. HTTP requests are passed to an instance of the HttpRuntime class, which represents the beginning of the pipe. The HttpRuntime object examines the request and figures out which application it was sent to (from the pipeline's perspective, a virtual directory is an application).
2. Then it uses an HttpApplicationFactory to either find or create an HttpApplication object to process the request. An HttpApplication, its modules, and its handler will only be used to process one request at a time. If multiple requests targeting the same application arrive simultaneously, multiple HttpApplication objects will be used
3. An HttpApplication holds a collection of HTTP module objects, implementations of the IHttpModule interface. HTTP modules are filters that can examine and modify the contents of HTTP request and response messages as they pass through the pipeline.
4. The HttpApplication object uses an HTTP handler factory to either find or create an HTTP handler object. HTTP handlers are endpoints for HTTP communication that process request messages and generate corresponding response messages. HTTP handlers and handler factories implement the IHttpHandler and IHttpHandlerFactory interfaces, respectively.





HTTP Handlers
 

 interface IHttpHandler
{
  // called to process request and generate response
  void ProcessRequest(HttpContext ctx);
  // called to see if handler can be pooled
  bool IsReuseable { get; }
}


The ProcessRequest method is called by an HttpApplication object when it wants the handler to process the current HTTP request and to generate a response. The IsReuseable property is accessed in order to determine whether a handler can be used more than once.

In addition to implementing custom handlers, you can also write your own handler factories. A handler factory is a simple class that implements the IHttpHandlerFactory interface. Handler factories are deployed the same way handlers are; the only difference is that the entry in the Web.config file refers the factory class instead of the handler class that the factory instantiates. If you implement a custom HTTP handler without implementing a handler factory, an instance of the pipeline-provided default factory class, HandlerFactoryWrapper, is used instead.

Standard Handlers





HTTP Modules
 
HTTP modules are filters that process HTTP request and response messages as they pass through the pipeline, examining and possibly modifying their content.


interface IHttpModule
{
  // called to attach module to app events
  void Init(HttpApplication app);
  // called to clean up
  void Dispose()
}
 
The Init method is called by an HttpApplication object when the module is first created. It gives the module the opportunity to attach one or 
more event handlers to the events exposed by the HttpApplication object. 

The Pipeline Event Model
 
 
 
In some cases, an HTTP module may want to influence the flow of processing in the pipeline. For example, a module that implements a security scheme might want to abort normal message processing and redirect the client to a login URL when it detects that the HTTP request message does not include a cookie identifying the user. The HttpApplication object exposes the CompleteRequest method. If an HTTP module's event handler calls HttpApplication.CompleteRequest, normal pipeline processing is interrupted after the current event completes (including the processing of any other registered event handlers). A module that terminates the normal processing of a message is expected to generate an appropriate HTTP response message.

If a module aborts normal message handling during an event handler by calling CompleteRequest, the ASP.NET HTTP pipeline interrupts processing after that event completes. However, EndRequest and the events that follow are still fired. 

Application Object

ASP.NET HTTP pipeline treats each virtual directory as an application. When a request for a URL in a given virtual directory arrives, the HttpRuntime object that dispatches the message uses an HttpApplicationFactory object to find or create an HttpApplication object to process the request. A given HttpApplication object will only be used to service requests sent to a single virtual directory, and there can be multiple pooled instances of HttpApplication for the same virtual directory.

If you want, you can customize the behavior of the HttpApplication class for your application (virtual directory). You do this by writing a global.asax file. If the HTTP pipeline detects a global.asax file in your virtual directory, it compiles it into an HttpApplication-derived class. Then it instantiates your specialized HttpApplication subclass and uses it to service requests.

There are three categories of events handled by the Application object

1. Events fired by HTTP Pipeline i.e. fired by the Application class itself
2. Application-level events i.e. Application_OnStart and Application_OnEnd.
3. Events fired by HTTP Modules

http://msdn.microsoft.com/en-us/magazine/cc188942.aspx

http://stackoverflow.com/questions/1739164/http-handlers-when-to-use-synchronous-asynchronous-generic-handlers-ashx