Utilizzo del polling nelle applicazioni console (ADO.NET)

Le operazioni asincrone in ADO.NET consentono di avviare operazioni di database che potrebbero richiedere molto tempo su un singolo thread e di eseguire altre attività su un thread diverso. Tuttavia, nella maggior parte degli scenari si raggiungerà un punto in cui l'applicazione non continuerà finché l'operazione di database non è completata. In questi casi, risulta utile effettuare il polling dell'operazione asincrona per determinare se l'operazione è stata completata.

È possibile utilizzare la proprietà IsCompleted per verificare se l'operazione è stata completata.

Esempio

La seguente applicazione console consente di aggiornare in modo asincrono i dati contenuti nel database di esempio AdventureWorks. Per emulare un processo a esecuzione prolungata, in questo esempio viene inserita un'istruzione WAITFOR nel testo del comando. In genere, non si consiglia di rallentare l'esecuzione dei comandi, ma in questo caso ciò consente di illustrare in modo semplice il comportamento asincrono.

[Visual Basic]

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 "Data Source=(local);Integrated Security=SSPI;" & _
          "Initial Catalog=AdventureWorks; " & _
          "Asynchronous Processing=true"
    End Function
End Module 

[C#]

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 "Data Source=(local);Integrated Security=SSPI;" +
        "Initial Catalog=AdventureWorks; " + 
        "Asynchronous Processing=true";
    }
}

Vedere anche

Altre risorse

Operazioni asincrone (ADO.NET)