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.
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)
Aucun commentaire:
Enregistrer un commentaire