Evitar se me "congele" mi aplicacion

22/07/2008 - 16:10 por Rick | Informe spam
Que tal foro, una duda

Tengo una aplicacion que carga datos de una db, es un SP, que se tarda unos
segundos en ejecutarse, se carga cuando inicia la app y pues no hay lio, el
problema es que despues, por medio de un timer cada 5 o 10 segundos, mando
llamar de nuevo a ese SP y mientras se ejecuta la aplicacion se congela, no
sigue su ejecucion normal, hasta que termina de ejecutarse el SP ya puedes
seguir trabajando, pero dado el timer pues es muy latoso que cada X segundos
se congele la aplicacion, intenté llamar a ese SP por medio de un
backgroundworker y nada, hace lo mismo (se congela por X segundos), por
medio de un hilo y tampoco =(


Que otra opcion tengo? o que me recomiendan hacer?


Saludos!!

Preguntas similare

Leer las respuestas

#1 Alberto Poblacion
22/07/2008 - 17:34 | Informe spam
"Rick" wrote in message
news:
Mostrar la cita
Algo tienes que estar haciendo mal. Tanto el BackgroundWorker como el
hilo te permiten que la aplicación siga funcionando mientras se ejecuta el
procedimiento, si los usas correctamente.

Mostrar la cita
Si tienes el Framework 2.0 o posterior, también puedes usar los métodos
asíncronos de ado.net, como por ejemplo el BeginExecuteNonQuery junto con su
EndExecuteNonQuery. Al igual que el BackgroundWorker y el Hilo, hay que
usarlo correctamente, por ejemplo, si llamas al EndExecuteNonQuery antes de
que haya concluido la ejecución del procedimiento, el programa se
"congelará" como si no hubieses empleado el método asíncrono.
#2 Rick
22/07/2008 - 23:12 | Informe spam
Ok, mira lo que hago es esto:


private void tmrCteExtra_Tick(object sender, EventArgs e)

{

//AGREGAR CLIENTES QUE NO ESTABAN CONECTADOS POR EL SP

if(backgroundWorker1.IsBusy==false)

backgroundWorker1.RunWorkerAsync();

//AGREGAR CLIENTES QUE NO ESTABAN CONECTADOS POR EL SP

}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)

{

this.AgregaNuevoCte();

}

private void AgregaNuevoCte()

{

NpgsqlConnection Cnn = new
NpgsqlConnection(Properties.Settings.Default.PgSQLCnn);

NpgsqlCommand Cmd = new NpgsqlCommand("",Cnn);

NpgsqlDataReader rdr;

Int32 liImg = 0; ;

String lsEstado = "";

Boolean encontrado = false;

try

{

Cnn.Open();

Cmd.CommandText = "select * from web_lista_users ('" + gsCve_Usuario +
"','G',0,'E') order by cve_user";

rdr = Cmd.ExecuteReader();

while (rdr.Read())

{

encontrado = false;

for (int i = 0; i < tvCliente.Nodes[0].Nodes.Count; i++)

{

if (rdr["usuario"].ToString() == tvCliente.Nodes[0].Nodes[i].Text)

{

encontrado = true;

}

}

if (!encontrado)

{

liImg = 1;

lsEstado = "En Linea";

TreeNode Nodo = new TreeNode(rdr["usuario"].ToString(), liImg, liImg);

Nodo.ToolTipText = lsEstado;

Nodo.Tag = rdr["cve_user"].ToString();

tvCliente.Nodes[0].Nodes.Add(Nodo);

}

}

rdr.Close();

tvCliente.ExpandAll();

}

catch (Exception ex)

{

MessageBox.Show(ex.Message + "El sistema se cerrar ahora.");//+
"f1-load");

this.Close();

}

finally {

if (Cnn.State == ConnectionState.Open) { Cnn.Close(); }

}

}


Como vez, solo agrego a un treeview, pero nada de endexecute ni nada por el
estilo =(

"Alberto Poblacion"
escribió en el mensaje news:%
Mostrar la cita
#3 Alberto Poblacion
23/07/2008 - 09:08 | Informe spam
"Rick" wrote in message
news:%23tHdp%
Mostrar la cita
En principio, el mecanismo de llamada que has hecho parece correcto, y
la operación de acceso a base de datos debería estarse realizando en el hilo
del backgroundworker sin bloquear el hilo de la interfaz de usuario. Por lo
menos, no detecto nada que lo impida con un examen visual del código que has
puesto.

Mostrar la cita
Puede que el problema esté ahi. La insterfaz de usuario en Windows Forms
es monohilo, lo que significa que no se pueden manipular los elementos de
pantalla (como el TreeView) desde un hilo distinto. Fíjate bien que en la
documentación del backgroundworker te lo advierte expresamente: "Note: You
must be careful not to manipulate any user-interface objects in your DoWork
event handler. Instead, communicate to the user interface through the
ProgressChanged and RunWorkerCompleted events." Y si en vez del
BackgroundWorker utilizaras un Hilo o un método asíncrono, te ocurriría
exactamente lo mismo aunque la documentación no lo advierta.

Lo que tienes que hacer es usar el segundo hilo para guardar en
variables los resultados de la consulta a base de datos, y una vez que
tengas los datos, pasárselos al hilo principal para que éste los traslade a
pantalla. La documentación del BackgroundWorker te explica cómo hacer este
paso al hilo principal: usando los eventos ProgressChanged o
RunWorkerCompleted. Si en lugar del BackgroundWorker estuvieras usando un
Thread, el paso al hilo principal lo harías con un this.Invoke(rutina).

Si a pesar de eso se te sigue bloqueando, tendrás que usar el
"debugger" sobre tu código fuente para ver dónde se bloquea y determinar
paso a paso cómo se ha llegado a esa situación.
#4 Rick
25/07/2008 - 01:23 | Informe spam
Okas dejame intentar a ver que pasa

Saludos!!!

"Alberto Poblacion"
escribió en el mensaje news:
Mostrar la cita
#5 alfonso_C#
29/07/2008 - 02:30 | Informe spam
On 24 jul, 19:23, "Rick" wrote:
Mostrar la cita
Lo que te propone Alberto es correcto debes usar el evento
RunWorkerCompleted del Backgroundworker para pasar el control al hilo
principal. A mi me sucedia lo mismo y usandolo de este modo todo ha
funcionado muy bien.
Ads by Google
Search Busqueda sugerida