Async Pages,Async Task in ASP.NET 2.0 and a little gotcha

Posted: October 11, 2005 in Uncategorized
Going to the async way and doing things Async way realted to new threads and improper way of doing the same leads to amny poor design and has significant issues .On the other hand doing things the async way provides a lot more flexibility and improve the performance a lot .Micosoft has keep this in mind and wisely provided many enhanced features of doing things the async way in vs2005-and asp.net2.0
Now you have the async way of executing ur reader usign the beginexecuting reader,the backgroundworker class and ASync pages as well as you have now the new anonymous methods.
Out of all these the challenges to handle the Async Calls in ASP.NET was always have some new overheads and doing the same in ASP.NET in an efficient manner is assocoiated with more overhead.If you want an efficient mechanism in asp.net 1.1 Fritz onion ‘s article on the same you should must go thru
Async pages in Asp.net 2.0 is one of the great features and For sure it is gonna goign to be a  must for every efficient Architect and developer .The async pages is a very neat and cool feature and declaring the Async=true in page directive gives  you all the necessary interfaces..and later you need to implement ur mechanism of async call based on it.
I am not going to write in details of the async pages wrokign here  as Jeff Prosise  ‘s article  on MSDNMAG here is describing the same in dept.
Now about the small gotcha:-If you are following the same article and runnign the code you ll found that :-
The Databind.aspx is not returnign the result.The problem was however due to the fact that the Page_PreRenderComplete method is getting called twice and this behavior is there for all pages including the webservice calls.I ve the RC build and I am now goign to send mail to verify this behavior.if you ve faced similar problem here is the workaround:-

to restrict the Page_PreRenderComplete  get called twice you can use

void

EndAsyncOperation(IAsyncResult ar)

{

_reader = _command.EndExecuteReader(ar);

this.PreRenderComplete -= new EventHandler(Page_PreRenderComplete);

}

 else make check on empty datareader

protected

void Page_PreRenderComplete(object sender, EventArgs e){

if (_reader.Read())

{

Gridview1.DataSource = _reader;

Gridview1.DataBind(); 

}

 }

but still the page_prerendercomplete ll invoked twice .
However the functionality of providing Asynchronous access is not within Page and you can have the AsyncTask as well.Read the same in the above Article from JEff as well as in fritz’s post here.
The uniqueness of the AsyncTask is that you can make multiple call,have a control over the timeout ,pass the state .
Further the above mentioned problem of  Page_PreRenderComplete firing twice for the Async Pages didn’t happens there.
(GOT THE ROOT OF THE PROBLEM IT SEEMS THAT THE PAGE_PRERENDER HOOKED AUTOMATICALLY ONCE YOU SET ASYNC=TRUE THUS WHEN i MYSELF IN CODE HOOKED THE SAME IT FIRED TWICE.THIS was not documneted but i should have noticed it before  ..thansks to olson for pointing the same)

if

(!IsPostBack){

// Hook PreRenderComplete event for data binding//this.PreRenderComplete += new EventHandler(Page_PreRenderComplete);// Register async methodsAddOnPreRenderCompleteAsync(

newBeginEventHandler(BeginAsyncOperation),

newEndEventHandler(EndAsyncOperation));

}

The Prerender now  fired once only .
 
 
 
Here you go for the async tasks :note i am not using timeout here:-
 
 

private

SqlConnection _connection;privateSqlCommand _command;

privateSqlDataReader _reader;

protectedvoid Page_Load(object sender, EventArgs e)

{

if (!Page.IsPostBack)

{

PageAsyncTask task = newPageAsyncTask

(

newBeginEventHandler(BeginAsyncOperation),

newEndEventHandler(EndAsyncOperation),

null,

null

);

RegisterAsyncTask(task);

}

}

IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)

{

string connect = WebConfigurationManager.ConnectionStrings[“PubsConnectionString”].ConnectionString;

_connection =

newSqlConnection(connect);

_connection.Open();

_command =

newSqlCommand(“SELECT title_id, title, price FROM titles”, _connection);

return _command.BeginExecuteReader(cb, state);

}

void EndAsyncOperation(IAsyncResult ar)

{

_reader = _command.EndExecuteReader(ar);

}

protectedvoid Page_PreRenderComplete(object sender, EventArgs e)

{

GridView1.DataSource = _reader;

GridView1.DataBind();

}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s