Example of Asynchronous page processing in ASP.net webforms (.NET 2.0) Example of Asynchronous page processing in ASP.net webforms (.NET 2.0) asp.net asp.net

Example of Asynchronous page processing in ASP.net webforms (.NET 2.0)


I asked some folks on the ASP.NET team. Here's their emailed response to me, and now, to you.

All that code ends up doing is spinning up a new thread and performing delegate invocation on that thread. So now there are two threads running: the request thread and the new thread. Hence this sample actually has worse performance than the original synchronous code would have had.

See http://www.asp.net/web-forms/tutorials/aspnet-45/using-asynchronous-methods-in-aspnet-45 for a sample on how to write and consume async methods in ASP.NET.


Here is a simple example of asynchronous processing.

   protected void Page_Load(object sender, EventArgs e)    {        ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));        ThreadPool.QueueUserWorkItem(state => Dokimes_Programming_multithread_QueryWorkThead.ThreadProc2());        Debug.Write("Main thread does some work, then sleeps.");        // If you comment out the Sleep, the main thread exits before        // the thread pool task runs.  The thread pool uses background        // threads, which do not keep the application running.  (This        // is a simple example of a race condition.)        // Thread.Sleep(4000);        txtDebug.Text += "ended";        Debug.Write("end.");    }    // This thread procedure performs the task.    static void ThreadProc(Object stateInfo)    {        // No state object was passed to QueueUserWorkItem, so  stateInfo is null.        Debug.Write(" Hello from the thread pool 1.");    }    static void ThreadProc2()    {        // No state object was passed to QueueUserWorkItem, so  stateInfo is null.        Debug.Write("Hello from the thread pool 2.");    }

Other way

You can use the PageAsyncTask, see here a full example:
http://msdn.microsoft.com/en-us/library/system.web.ui.pageasynctask.aspx

Something like

clAsynCustomObject oAsynRun = new clAsynCustomObject();PageAsyncTask asyncTask = new PageAsyncTask(oAsynRun.OnBegin, oAsynRun.OnEnd, oAsynRun.OnTimeout, null, true);Page.RegisterAsyncTask(asyncTask);Page.ExecuteRegisteredAsyncTasks();


I think I discovered how to do what I wanted to accomplish... though it may not be the best way, feel free to chime in.

At the time of writing there was only one answer in this thread, by Aristos. While he gave an example of executing an asynchronous request, what I wanted was a way to tell ASP.NET to execute some long running method, release the IIS thread so it can be available to service other requests, and then come back when the method finished.

Here's what I came up with, using the same (or similar) example in the question:

using System;using System.Collections.Generic;using System.Threading;using System.Web.UI;namespace WebApplication2{    public class MyEntity    {        public string Name { get; set; }    }    public class MyRepository    {        public List<MyEntity> GetEntities(string param1, string param2)        {            Thread.Sleep(10000);            return new List<MyEntity> {new MyEntity {Name = "John Smith"}};        }    }    public partial class Default : Page    {        private readonly MyRepository _myRepository = new MyRepository();        private List<MyEntity> _myEntities;        protected void Page_Load(object sender, EventArgs e)        {        }        private void DoStuffWithEntities()        {            Response.Write("<br/><br/><b>" + _myEntities[0].Name + "</b><br/><br/>");        }        protected void _btnProcess_Click(object sender, EventArgs e)        {            AddOnPreRenderCompleteAsync(BeginExecution, EndExecution, null);        }        private void GetEntities()        {            string param1 = _txtParam1.Text;            string param2 = _txtParam2.Text;            //This takes a long time (relative to a web request)            _myEntities = _myRepository.GetEntities(param1, param2);        }        private IAsyncResult BeginExecution(object sender, EventArgs e, AsyncCallback callback, object state)        {            var t = new ThreadStart(GetEntities);            return t.BeginInvoke(callback, null);        }        private void EndExecution(IAsyncResult result)        {            //Conceptually, I would like IIS to bring up a new thread here so that I can            //display the data after it has come back.            DoStuffWithEntities();        }    }}