Dajbych.net


ASP.NET Web User Control and its Parallel Processing

, 2 minutes to read

net2010 logo

If we program Web User Control whose task is only to download information from another website, process it and return the appropriate HTML code, it is nothing earth-shattering. The page containing the control takes a little longer to load for the first time, other requests are handled quickly thanks to ASP.NET Caching, or thanks to the implementation of the Proxy design pattern. However, if we have twenty controls on a page and each of them needs to download something different, the situation starts to get a bit dramatic.

There is no parallelism in the HTTP response generation ASP.NET the Engine itself. It is used to process multiple HTTP requests simultaneously. The individual controls are gradually generated one by one. If it takes 0.7 seconds to generate one control, then a page containing twenty such controls will take 14 seconds to load. Generating reports or calling slow web services can be very unpleasant.

In some cases, the characteristics of the data and the frequency of their reading allow the external content to be downloaded in procedure Application_Start and the control only picks it up. But then the beauty of the control is lost, which lies in the fact that we define its content using parameters. If each parameter value is registered somewhere so that the content is loaded at application startup, it may happen that the overview of which content is used in which page will be lost. In addition, the application will load a lot of data at startup, which is especially unpleasant during its development.

To parallel processing of controls on a page, ASP.NET technology is Asynchronous Web Parts. Without it, the control would look something like this:

public partial class WebUserControl : System.Web.UI.UserControl {

    Thread thread;
    string result;
    
    protected override void OnInit(EventArgs e) {
        thread = new Thread(new ThreadStart(HardWork));
        thread.Priority = ThreadPriority.AboveNormal;
        thread.Start();
    }

    private void HardWork() {
        for (int suma = 0; suma < 7; suma++) Thread.Sleep(100);
        result = "výsledek";
    }

    protected override void Render(HtmlTextWriter writer) {
        thread.Join();
        writer.Write(string.Format("<strong>{0}</strong>", result));
    }
    
}

If we start doing something in the control in another thread, the work must be done in procedure Render. It makes sense to start executing something in a procedure OnInit when the properties of the control are already set. ASP.NET we OnInit run all threads sequentially in procedures. The procedures are finished, so we continue working on the page until finally in procedure Render using Join() we wait for all threads to finish.

Asynchronous Web Parts shall apply mutatis mutandis. The control must implement the IAsyncResult interface, and the page whose controls are to be generated in parallel must contain the Async="true" parameter.