Asynchronous processing on the Command object

As we already know that the object command run synchronously as default query processing. In ADO.NET 2.0 Microsoft has been added the feature to fulfill the requirement for the asynchronous processing. The process signed with the BeginExecute...and EndExecute...method, for example if we want to execute the query for the Select statement via DataReader we should use BeginExecuteReader and EndExecuteReader method instead of ExecuteReader.

There are some steps we have to do for doing asynchronous processing. One of the step is add the "Asynchronous Processing=True" attribute in the connection string. The .net runtime environment will knows what he has to do. The other steps are creating the delegate to create the object from the delegate for passing into the Invoke method as the parameter in the final asynchronous process. Calling the Invoke method is the must. It moves the result of async processing from the thread to the windows main thread. The Invoke method takes two argument to passed by. The first argument is the delegate object, the second is the array of objects to pass to the method. If the method contains no parameter or argument then the value of the object array can be set to null.

In this article i will show you the simple example to do the async processing of the command object. The scenario is executing the query that takes long time to finished. We can create a tricky procedure to accomplish this by writing the stored procedure contains the "WAITFOR DELAY" function to stop the executing query for a moment. For briefly,  let us consider the whole following steps below :

1. Create the stored procedure that takes long time to finished :

ALTER Proc LongRunningQuery
As
WaitFor Delay '0:0:10'
Select * From [Order Details]

It simply stop the execution just for 10 second, after that the query continue processing.

2. Create a simple windows application project. Put a button and datagridview control onto the form. The scenario is we want to execute the query from the stored procedure above via SqlDataReader asynchronously. The SqlDataReader will be used by DataTable as datasource for DataGridView control for Binding. Let's see the code fragment :

Imports System.Data.SqlClient

Public Class frmAsyncCommand

    Private sqlCon As SqlConnection
    Private sqlConnBuilder As SqlConnectionStringBuilder
    Private sqlCmd As SqlCommand

    Private Delegate Sub GetDataDelegate(ByVal YourTable As DataTable)

I use the new SqlConnectionStringBuilder class for giving us a strongly typed connection string. The GetDataDelegate sub created as Delegate that will be used by the Invoke method as parameter.

    Private Sub GetDataFromOrderDetails(ByVal YourTable As DataTable)
        Me.DataGridView1.DataSource = Nothing
        Me.DataGridView1.DataSource = YourTable
    End Sub

 the GetDataFromOrderDetails sub is the procedure for passing into the Invoke method as the delegate object parameter. Consider that the signature has the same with the delegate sub created before. It just simply do the data binding for DataGridView control.

    Private Sub EndOfAsyncProc(ByVal ar As IAsyncResult)
        Dim sqlCmd As SqlCommand = CType(ar.AsyncState, SqlCommand)
        Dim sqlDr As SqlDataReader = sqlCmd.EndExecuteReader(ar)

        Dim dtOrderDetails As New DataTable
        dtOrderDetails.Load(sqlDr)

        sqlCmd.Dispose()
        sqlDr.Close()
        sqlCon.Close()

        Me.Invoke(New GetDataDelegate(AddressOf GetDataFromOrderDetails), _
        New Object() {dtOrderDetails})
    End Sub

 the main duty in the EndOfAsyncProc procedure is converting async result to the previous object, that is SqlCommand, then finishing the ExecuteReader with call EndExecuteReader. The Invoke method take the final step to move the process from the thread back into the windows main thread. It give us no meaningfull process if we do not call the Invoke method due to the separating thread.

The last is a procedure to create asynchronous processing. We only just add the "AsynchronousProcessing" property to the connection string via SqlConnectionStringBuilder class and set the value to true. The async processing begin with calling BeginExecuteReader method from command object and passing the procedure as the argument to the method that will be executed when the thread is finish...

    Private Sub btnAsyncCommand_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAsyncCommand.Click
        sqlConnBuilder = New SqlConnectionStringBuilder
        With sqlConnBuilder
            .DataSource = ".\SQLDEV2K5"
            .InitialCatalog = "Northwind2K5"
            .IntegratedSecurity = True
            .AsynchronousProcessing = True
        End With
        sqlCon = New SqlConnection(sqlConnBuilder.ToString)

        If sqlCon.State <> ConnectionState.Open Then sqlCon.Open()

        Using sqlCmd As New SqlCommand
            sqlCmd.CommandType = CommandType.StoredProcedure
            sqlCmd.Connection = sqlCon
            sqlCmd.CommandText = "LongRunningQuery"
            sqlCmd.BeginExecuteReader(AddressOf EndOfAsyncProc, sqlCmd, _
            CommandBehavior.CloseConnection)
        End Using
    End Sub
End Class

 

Share this post: | | | |
Published Friday, April 20, 2007 8:56 AM by yulian
Filed under:

Comments

# re: Asynchronous processing on the Command object

Friday, April 20, 2007 4:42 PM by norman

Hmm... Asynchronous di implement dgn IAsyncResult Pattern, padahal at the same time Microsoft promote Event-Based Pattern utk Asynchronous Programming.

Liat di Proxy class generate-an Visual Studio utk Web Service deh. Di sana sdh pakai Event-Based Pattern. Kayaknya team ADO.NET belum sempat implement style yg baru ini. :)

More on Event-Based Pattern for Asynchronous Programming:

http://geeks.netindonesia.net/blogs/norman/archive/2005/12/21/8188.aspx

# re: Asynchronous processing on the Command object

Friday, April 20, 2007 4:45 PM by norman

Mau nambah: :)

See the Guidelines here: http://msdn2.microsoft.com/en-us/library/ms228966(VS.80).aspx

# re: Asynchronous processing on the Command object

Friday, April 20, 2007 4:56 PM by yulian

yup...betul mas norman.sebenarnya di proxy class yang di generate di xml web services sdh ada fitur untuk async programming semenjak versi .net pertama kali keluar. tapi untuk object command baru ada di versi ado.net 2.0 secara langsung fiturnya dengan penambahan atribut "asynchronous processing=true" di connection string. kenapa ga dari dulu ya? :)

Powered by Community Server (Commercial Edition), by Telligent Systems