Frédéric Colin
Appels asynchrones en ADO.NET 2.0
ADO.NET V2 apporte une simplification appréciable pour exécuter de manière asynchrone des requêtes en BD pour l'espace de nom SqlClient. Ce petit exem
Par Frédéric Colin publié le 25/09/2005 à 20:01, lu 14998 fois,
Téléchargez le code source - 15 Kb
L'exemple
Un peu à la façon des proxies Web Services générés automatiquement par Visual Studio 2003 lors de leur référencement, la classe « System.Data.SqlClient.SqlCommand » propose de nouvelles méthodes « Begin* » et « End* » permettant d'exécuter de manière asynchrone des requêtes sur une base de données SQL Server. Par exemple :
  • BeginExecuteNonQuery : le pendant de ExecuteNonQuery pour les requêtes actions asynchrones.
  • BeginExecuteReader : le pendant de ExecuteReader pour la récupération d'un jeu de données en asynchrone.
Voici donc les grandes étapes pour récupérer un jeu de données de manière asynchrone sur SQL Server :
  • Etape 1 : création d'un délégué qui permettra de définir une signature afin de lier un IDataReader à une DataGridView :
    // Delegue definissant la mise  jour la grille lors du callback
    public delegate void ProcessDelegate(IDataReader dr);
    
  • Etape 2 : création de la méthode exécutée en fin d'appel asynchrone et qui utilisera le délégué précédent pour lier le IDataReader à la DataGridView. Vous noterez l'utilisation de la propriété « InvokeRequired » afin de vérifier si le handle du contrôle a été créé sur un autre Thread ou pas (utile pour la liaison puisque cette dernière ne peut se faire que sur le même Thread que celui qui a créé le contrôle) :
    // Methode executee en callback
    private void ExecuteOnCallBack(IAsyncResult result)
    {
        // Recuperation de la commande initiale passee en parametre lors du BeginExecuteReader
        SqlCommand cmd = (SqlCommand)result.AsyncState;
    
        SqlDataReader reader = cmd.EndExecuteReader(result);
    
        // Verifie si le handle du controle a ete cree sur un autre Thread ou pas. 
        if (dataGridView1.InvokeRequired)
            dataGridView1.Invoke(new ProcessDelegate(Process), new object[] { reader });
        else
            Process(reader);
    }
    
    
  • Etape 3 : création de la méthode permettant de lier le IDataReader à la DataGridView selon le modèle défini par le délégué précédent :
    // Methode executee pour realiser la liaison de donnees
    public void Process(IDataReader dr)
    {
        BindingSource source = new BindingSource();
        source.DataSource = dr;
        dataGridView1.DataSource = source;
    
        dr.Close();
    }
    
  • Etape 4 : Codage de l'appel asynchrone. Vous noterez la modification de la chaîne de connexion : « async=true » :
    private void Form1_Load(object sender, EventArgs e)
    {
        // La chaine de connexion doit etre positionnee dans un fichier de configuration. En dur dans le code, c'est Mal !
        string connectionString = "data source=(local);initial catalog=Northwind;user id=sa;password=XxXx;async=true";
    
        SqlConnection cn = new SqlConnection(connectionString);
    
        cn.Open();
    
        SqlCommand cmd = cn.CreateCommand();
    
        cmd.CommandText = "sSelectOrdersDetail";
        cmd.CommandType = CommandType.StoredProcedure;
    
        // Appel asynchrone
        IAsyncResult iar
            = cmd.BeginExecuteReader
                (
                    new AsyncCallback(ExecuteOnCallBack),
                    cmd,
                    CommandBehavior.CloseConnection
                );
    }
    
L'exemple que vous trouverez en attache permet d'exécuter une procédure stockée sur la base exemple Northwind sur SQL Server 2000. Vous noterez l'utilisation dur « WAITFOR » pour simuler un long traitement :
CREATE PROCEDURE dbo.sSelectOrdersDetail
    (
        @OrderID INT = NULL
    )

AS
BEGIN
    WAITFOR DELAY '000:00:10'
    SELECT     [Order Details].*
    FROM         [Order Details]
    WHERE     ( (@OrderID IS NULL) OR (OrderID = @OrderID) )
END
Cet article a été réalisé sur les versions suivantes :
  • Framework .NET version 2.0.50215
  • Visual Studio 2005 version 8.0.50215.44 (beta2.050215-4400)
 
» Démarrer une discussion