Sondeo de aplicaciones de consola
Las operaciones asincrónicas en ADO.NET permiten iniciar operaciones de base de datos que consumen mucho tiempo en un subproceso mientras se realizan otras tareas en otro subproceso. Sin embargo, en la mayoría de los escenarios llegará a un punto en el que la aplicación no debería continuar hasta que se complete la operación de base de datos. En estos casos, resulta útil sondear la operación asincrónica para determinar si la operación se ha completado o no.
Puede usar la propiedad IsCompleted para averiguar si se ha completado o no la operación.
Ejemplo
La siguiente aplicación de consola actualiza los datos de la base de datos de ejemplo AdventureWorks y lo hace de forma asincrónica. Para emular un proceso de ejecución prolongada, en este ejemplo se inserta una instrucción WAITFOR en el texto del comando. Normalmente, no intentaría que los comandos se ejecutaran más lentamente, pero en este caso facilita la demostración del comportamiento asincrónico.
Imports System
Imports System.Data.SqlClient
Module Module1
Sub Main()
' The WAITFOR statement simply adds enough time to prove the
' asynchronous nature of the command.
Dim commandText As String = _
"UPDATE Production.Product " & _
"SET ReorderPoint = ReorderPoint + 1 " & _
"WHERE ReorderPoint Is Not Null;" & _
"WAITFOR DELAY '0:0:3';" & _
"UPDATE Production.Product " & _
"SET ReorderPoint = ReorderPoint - 1 " & _
"WHERE ReorderPoint Is Not Null"
RunCommandAsynchronously(commandText, GetConnectionString())
Console.WriteLine("Press Enter to continue.")
Console.ReadLine()
End Sub
Private Sub RunCommandAsynchronously( _
ByVal commandText As String, ByVal connectionString As String)
' Given command text and connection string, asynchronously
' execute the specified command against the connection. For
' this example, the code displays an indicator as it's working,
' verifying the asynchronous behavior.
Using connection As New SqlConnection(connectionString)
Try
Dim count As Integer = 0
Dim command As New SqlCommand(commandText, connection)
connection.Open()
Dim result As IAsyncResult = _
command.BeginExecuteNonQuery()
While Not result.IsCompleted
Console.WriteLine("Waiting ({0})", count)
' Wait for 1/10 second, so the counter
' doesn't consume all available resources
' on the main thread.
Threading.Thread.Sleep(100)
count += 1
End While
Console.WriteLine( _
"Command complete. Affected {0} rows.", _
command.EndExecuteNonQuery(result))
Catch ex As SqlException
Console.WriteLine("Error ({0}): {1}", _
ex.Number, ex.Message)
Catch ex As InvalidOperationException
Console.WriteLine("Error: {0}", ex.Message)
Catch ex As Exception
' You might want to pass these errors
' back out to the caller.
Console.WriteLine("Error: {0}", ex.Message)
End Try
End Using
End Sub
Private Function GetConnectionString() As String
' To avoid storing the connection string in your code,
' you can retrieve it from a configuration file.
' If you have not included "Asynchronous Processing=true"
' in the connection string, the command will not be able
' to execute asynchronously.
Return "..." & _
"Asynchronous Processing=true"
End Function
End Module
using System;
using System.Data;
using System.Data.SqlClient;
class Class1
{
[STAThread]
static void Main()
{
// The WAITFOR statement simply adds enough time to
// prove the asynchronous nature of the command.
string commandText =
"UPDATE Production.Product SET ReorderPoint = " +
"ReorderPoint + 1 " +
"WHERE ReorderPoint Is Not Null;" +
"WAITFOR DELAY '0:0:3';" +
"UPDATE Production.Product SET ReorderPoint = " +
"ReorderPoint - 1 " +
"WHERE ReorderPoint Is Not Null";
RunCommandAsynchronously(
commandText, GetConnectionString());
Console.WriteLine("Press Enter to continue.");
Console.ReadLine();
}
private static void RunCommandAsynchronously(
string commandText, string connectionString)
{
// Given command text and connection string, asynchronously
// execute the specified command against the connection.
// For this example, the code displays an indicator as it's
// working, verifying the asynchronous behavior.
using (SqlConnection connection =
new SqlConnection(connectionString))
{
try
{
int count = 0;
SqlCommand command =
new SqlCommand(commandText, connection);
connection.Open();
IAsyncResult result =
command.BeginExecuteNonQuery();
while (!result.IsCompleted)
{
Console.WriteLine(
"Waiting ({0})", count++);
// Wait for 1/10 second, so the counter
// doesn't consume all available
// resources on the main thread.
System.Threading.Thread.Sleep(100);
}
Console.WriteLine(
"Command complete. Affected {0} rows.",
command.EndExecuteNonQuery(result));
}
catch (SqlException ex)
{
Console.WriteLine("Error ({0}): {1}",
ex.Number, ex.Message);
}
catch (InvalidOperationException ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
catch (Exception ex)
{
// You might want to pass these errors
// back out to the caller.
Console.WriteLine("Error: {0}", ex.Message);
}
}
}
private static string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
// If you have not included "Asynchronous Processing=true"
// in the connection string, the command will not be able
// to execute asynchronously.
return "..." + "Asynchronous Processing=true";
}
}