Introduction The applications generally need to compromise on performance and scalability when the modules/individual components of a site simultaneously make network requests for data or to the webservices. Whenever requests are made to a remote database, their individual processing time gets added up to the overall processing time of the page even though the requests are typically independent of each other and could possibly be made synchronously.
Making Data Requests Asynchronously The suggested solution is to perform asynchronous data retrieval with ADO.NET. You must be aware that Web service proxies already have mechanism for handling such asynchronous requests. We can however make use of the new asynchronous methods on the SqlCommand class and the asynchronous task feature of ASP.NET.
How to make asynchronous calls To begin data retrieval asynchronously, the Async attribute of the Pag directive should be set to true. . In simple terms it also mean that the page will free up the primary request thread to service other clients while waiting for the data.
<@ Page Language="C#" AutoEventWireup="true" Async="true" > The methods IAsyncResult BeginExecuteReader(AsyncCallback ac, object state) , IAsyncResult BeginExecuteNonQuery(AsyncCallback ac, object state) and IAsyncResult BeginExecuteXmlReader(AsyncCallback ac, object state) can be used to invoke asynchronous calls. In order to achieve asynchronisation the attribute "async=true" must be added to the connection string. I’ll illustrate this by populating a DataGrid with some data. If we are using SqlDataReader then it will be appropriate to use BeginExecuteReader method to initiate the asynchronous calls. We will need to register asynchronous tasks in the Page that need to be executed before the page completes rendering. This can be very well achieved in ASP.NET 2.0 using page async task.
Page.RegisterAsyncTask(new PageAsyncTask( new BeginEventHandler(BeginGetSalesData), new EndEventHandler(EndGetSalesData), new EndEventHandler(GetSalesDataTimeout), null, true));
RegisterAsyncTask is initialized with three delegates: begin handler, end handler, and timeout handler. The begin handler is utilized to make asynchronous data request using BeginExecuteReader. It returns an IAsyncResult interface. The end handler is called once the task is complete , at which point data is returned and can be used. ASP.NET will take care of invoking the begin handler just before it relinquishes the request thread (immediately after the PreRender event completes). Once the data stream is ready to begin reading, the end commands SqlDataReader EndExecuteReader(IAsyncResult ar) , int EndExecuteNonQuery(IAsyncResult ar) or XmlReader EndExecuteXmlReader(IAsyncResult ar) can be used to complete the request.
The timeout handler is invoked only when the remote invocations fail to return in time. This timeout is declared in the Page directive using the AsyncTimeout attribute; it has a default value of 20 seconds.
Lets consider an example. In EmployeeInfo class we register Page for Async call back. BeginGetEmployeeAttendence is the begin handler that executes BeginExecuteReader to fetch the records.EndEmployeeAttendence is the EndHandler that completes the request call.
public partial class EmployeeInfo : UserControl { // Local variables to store connection and command // for async data retrieval SqlConnection _conn; SqlCommand _cmd;
protected void Page_Load(object sender, EventArgs e) { string dsn = ConfigurationManager. ConnectionStrings["employeeDB"].ConnectionString; dsn += ";async=true"; // Allow for asynchronous operations
string sql = "WAITFOR DELAY ‘00:00:03’ SELECT [empId], " + "[name], [date], [project] FROM " + "[employeeInfo] WHERE month=@month"; _conn = new SqlConnection(dsn); _cmd = new SqlCommand(sql, _conn); _conn.Open(); _cmd.Parameters.AddWithValue("@month", int.Parse(_monthTextBox.Text));
// Launch data request asynchronously using page async task Page.RegisterAsyncTask(new PageAsyncTask( new BeginEventHandler(BeginGetEmployeeAttendence), new EndEventHandler(EndEmployeeAttendence), new EndEventHandler(GetEmployeeAttendenceTimeout), null, true)); }
IAsyncResult BeginGetEmployeeAttendence (object src, EventArgs e, AsyncCallback cb, object state) { return _cmd.BeginExecuteReader(cb, state); }
void EndEmployeeAttendence(IAsyncResult ar) { _ employeeGrid.DataSource = _cmd.EndExecuteReader(ar); _ employeeGrid.DataBind(); _conn.Close(); }
void GetEmployeeAttendenceTimeout (IAsyncResult ar) { // operation timed out, so just clean up by closing the connection if (_conn.State == ConnectionState.Open) _conn.Close(); _messageLabel.Text = "Connection timed out..."; }
}
Summary The scalability and performance is considerably improved through asynchronous calls. You can be sure that the processing time taken by the page is less than the time taken when individual requests were processed across the network.
|
No responses found. Be the first to respond and make money from revenue sharing program.
|