En ciertas ocasiones, cuando trabajamos con grandes cantidades de datos al mismo tiempo las interfaces de nuestros programas pueden quedar bloqueadas. Esto generalmente hace que el usuario pierda la paciencia y termine cerrando la aplicación con la famosa combinación CTRL+ALT+SUPR.
Para evitarlo podemos hacer uso de los hilos de toda la vida o de la API asíncrona que nos ofrece ADO.NET:
Begin/EndExecuteNonQuery
Begin/EndExecuteReader
Begin/EndExecuteXmlReader
Es muy sencillo así que voy a mostrarlo con un ejemplo en el que hago múltiples inserciones en una tabla de la base de datos.
Lo primero que haremos es crear un objeto SqlConnection y otro SqlCommand:
SqlConnection conexion = new SqlConnection(@»Data Source=.SQLEXPRESS;AttachDbFilename=C:nordwindNORTHWND.MDF;Integrated Security=True; User Instance=True; asynchronous processing=true;«);
SqlCommand cmd;
StringBuilder consulta = new StringBuilder();
Ahora abrimos la conexión con la base de datos y en un objeto StringBuilder añado todas las inserciones que tengo que hacer.
try
{
conexion.Open();
for(int i=0;i<palabras.Length;i++)
{
consulta.Append(«INSERT into palabras (palabra) VALUES (‘» + palabras[i].ToString()+»‘);«);}
Cuando termina de crear todas las inserciones creo una instancia del SqlCommand al que le paso las inserciones y el objeto SqlConnection.
cmd = new SqlCommand(consulta.ToString(), conexion);
Para ejecutar el comando en otro hilo diferente al del programa principal preparo un delegado que se activara cuando termine la operación.
AsyncCallback callback = new AsyncCallback(MetodoCallBack);
Luego ejecuto el comando de forma asíncrona:
cmd.BeginExecuteNonQuery(callback, cmd);
Por último en la función que ejecuta el delegado recogemos el resultado de la operación y ejecutamos EndExecuteNonQuery.
SqlCommand cmd = (SqlCommand)result.AsyncState;
cmd.EndExecuteNonQuery(result);
El código completo sería el siguiente:
private void btnGuardar_Click(object sender, EventArgs e)
{
String[] palabras = txtTexto.Text.Split(« «.ToCharArray());
SqlConnection conexion = new SqlConnection(@»Data Source=.SQLEXPRESS;AttachDbFilename=C:ORTHWND.MDF;Integrated Security=True; User Instance=True; asynchronous processing=true;«);
SqlCommand cmd;
StringBuilder consulta = new StringBuilder();
try
{
conexion.Open();
for(int i=0;i<palabras.Length;i++)
{
consulta.Append(«INSERT into palabras (palabra) VALUES (‘» + palabras[i].ToString()+»‘);«);
}
cmd = new SqlCommand(consulta.ToString(), conexion);
AsyncCallback callback = new AsyncCallback(MetodoCallBack);
txtTexto.Enabled = false;
cmd.BeginExecuteNonQuery(callback, cmd);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void MetodoCallBack(IAsyncResult result)
{
SqlCommand cmd = (SqlCommand)result.AsyncState;
cmd.EndExecuteNonQuery(result);
txtTexto.Enabled = true;
cmd.Dispose();
}
Espero que os sirva.
Un saludo
Deja una respuesta