Thread´s, delegados muy muy lentos

03/05/2005 - 17:02 por Salva | Informe spam
Hola.
Necesito cargar un DataSet con una tabla de 50.000 registros. Para que el
usuario no se mosque quiero mostrar una barra de progreso que muestre el
proceso de carga.
He conseguido mostrar el progreso de carga en una progressbar mediante
Threads y delegados. El problema esta en que si no utilizo barra de progreso
ni nada y dejo que se bloque el formulario,sin thread ni na, me tarda unos 5
o 6 segundos en llenar la tabla. Pero como utilize un Thread para mostrar la
barra de progreso me tarda casi 1 min.
Hay alguna manera de hacer que no tarde tanto?
Lo hice utilizando el application.doevents en vez de thread y aun tarda mas.

Preguntas similare

Leer las respuestas

#6 Salva
04/05/2005 - 09:21 | Informe spam
El codigo fuente es el siguiente
'Es un formulario con un label donde va poniendo el numero de registro, 2
botones para iniciar y para. Y una barra de estado que tiene una progressbar.
La progressbar funciona igual que la que viene con el visual studio .net,
solo que es un componente de terceros. He probado con la que trae el visual
studio y hace lo mismo.
Muchas gracias.
Private Sub Datos()
Dim CN As New SqlClient.SqlConnection(Conexion)
Da = New SqlClient.SqlDataAdapter("SELECT * FROM TABLA", CN)
Da.Fill(Dt)
End Sub

Private Delegate Sub HacerProgresoDelegado(ByVal Retardo As Integer)

Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.st.Panels(0).ProgressBarInfo.Maximum = 50000
End Sub
Private Sub HacerProgreso(ByVal Retardo As Integer)
Dim cnt As Integer = 0
Proc.Start()
For cnt = 0 To 100
ProgresoEnCurso(cnt, String.Format("{0}% Hecho", cnt))
Next cnt
End Sub

Private Sub btIniciar_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btIniciar.Click
Cancelado = False
Cancelando = False
btIniciar.Enabled = False
Dim Progreso As New HacerProgresoDelegado(AddressOf HacerProgreso)
Progreso.BeginInvoke(0, New AsyncCallback(AddressOf
HacerProgresoCompleto), Progreso)
End Sub

Private Sub btParar_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btParar.Click
Cancelando = True
End Sub
Private Sub HacerProgresoCompleto(ByVal ProgresoID As IAsyncResult)
HabilitarBotonIniciar()
Dim Progreso As HacerProgresoDelegado
Progreso = ProgresoID.AsyncState
Progreso.EndInvoke(ProgresoID)
End Sub
Private Sub HabilitarBotonIniciar()
If (btIniciar.InvokeRequired) Then
btIniciar.Invoke(New MethodInvoker(AddressOf HabilitarBotonIniciar))
Else
btIniciar.Enabled = True
End If
End Sub
Private Delegate Sub ProgresoEnCursoDelegado(ByVal Valor As Integer, ByVal
mensaje As String)
Private Sub ProgresoEnCurso(ByVal Valor As Integer, ByVal mensaje As String)
If p.InvokeRequired Then
p.Invoke(New ProgresoEnCursoDelegado(AddressOf ProgresoEnCurso), New
Object() {Valor, mensaje})
Else
p.Value = Valor
lblEstado.Text = mensaje
End If
End Sub

Private Sub Dt_RowChanged(ByVal sender As Object, ByVal e As
System.Data.DataRowChangeEventArgs) Handles Dt.RowChanged
If e.Action = DataRowAction.Add Then
cnt += 1
ProgresoEnCurso(cnt, String.Format("{0}% Hecho", cnt))
End If
End Sub
Respuesta Responder a este mensaje
#7 Salva
04/05/2005 - 09:30 | Informe spam
Lo pongo otra vez porque se me olvido escribir las variables
El codigo fuente es el siguiente
'Es un formulario con un label donde va poniendo el numero de registro, 2
botones para iniciar y para. Y una barra de estado que tiene una progressbar.
La progressbar funciona igual que la que viene con el visual studio .net,
solo que es un componente de terceros. He probado con la que trae el visual
studio y hace lo mismo.
Muchas gracias.

'Variables
Dim Cancelado As Boolean = False
Dim Cancelando As Boolean = False
Dim cnt As Integer
Dim WithEvents Da As SqlClient.SqlDataAdapter
Dim WithEvents Dt As New DataTable
Dim Proc As New System.Threading.Thread(AddressOf Datos)
'Aqui iria el codigo generado por windows forms
Private Sub Datos()
Dim CN As New SqlClient.SqlConnection(Conexion)
Da = New SqlClient.SqlDataAdapter("SELECT * FROM TABLA", CN)
Da.Fill(Dt)
End Sub

Private Delegate Sub HacerProgresoDelegado(ByVal Retardo As Integer)

Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.st.Panels(0).ProgressBarInfo.Maximum = 50000
End Sub
Private Sub HacerProgreso(ByVal Retardo As Integer)
Dim cnt As Integer = 0
Proc.Start()
For cnt = 0 To 100
ProgresoEnCurso(cnt, String.Format("{0}% Hecho", cnt))
Next cnt
End Sub

Private Sub btIniciar_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btIniciar.Click
Cancelado = False
Cancelando = False
btIniciar.Enabled = False
Dim Progreso As New HacerProgresoDelegado(AddressOf HacerProgreso)
Progreso.BeginInvoke(0, New AsyncCallback(AddressOf
HacerProgresoCompleto), Progreso)
End Sub

Private Sub btParar_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btParar.Click
Cancelando = True
End Sub
Private Sub HacerProgresoCompleto(ByVal ProgresoID As IAsyncResult)
HabilitarBotonIniciar()
Dim Progreso As HacerProgresoDelegado
Progreso = ProgresoID.AsyncState
Progreso.EndInvoke(ProgresoID)
End Sub
Private Sub HabilitarBotonIniciar()
If (btIniciar.InvokeRequired) Then
btIniciar.Invoke(New MethodInvoker(AddressOf HabilitarBotonIniciar))
Else
btIniciar.Enabled = True
End If
End Sub
Private Delegate Sub ProgresoEnCursoDelegado(ByVal Valor As Integer, ByVal
mensaje As String)
Private Sub ProgresoEnCurso(ByVal Valor As Integer, ByVal mensaje As String)
If p.InvokeRequired Then
p.Invoke(New ProgresoEnCursoDelegado(AddressOf ProgresoEnCurso), New
Object() {Valor, mensaje})
Else
p.Value = Valor
lblEstado.Text = mensaje
End If
End Sub

Private Sub Dt_RowChanged(ByVal sender As Object, ByVal e As
System.Data.DataRowChangeEventArgs) Handles Dt.RowChanged
If e.Action = DataRowAction.Add Then
cnt += 1
ProgresoEnCurso(cnt, String.Format("{0}% Hecho", cnt))
End If
End Sub
Respuesta Responder a este mensaje
#8 Pablo Fébolo
04/05/2005 - 14:24 | Informe spam
Si le pones la siguiente modifiación (el IF)

If e.Action = DataRowAction.Add Then
cnt += 1


if (cnt mod 500) = 0 then
ProgresoEnCurso(cnt, String.Format("{0}% Hecho", cnt))


end if
End If





La cantidad de veces que se debera refrescar el progressbar y el label
sera 100 veces menor, con lo que posiblemente mejor en significativamente
el tiempo total de proceso.
Respuesta Responder a este mensaje
#9 Salva
04/05/2005 - 15:46 | Informe spam
Si, va mas rapido. Pero lo que yo queria sabe es si el hecho de abrir un
proceso a parte como es en este caso quita tanto rendimiento al programa
princiapal. Yo pensaba tardaria igual, puesto que se ejecuta aparte ¿no?
Muchas gracias por la ayuda.
Respuesta Responder a este mensaje
#10 Pablo Fébolo
04/05/2005 - 18:39 | Informe spam
El problema no esta en le proceso aparte,
sino en el refresco del progressbar y del label,
es por eso que al refrescarlo 100 veces menos
va mas rápido.

Por ejemplo podes probar comentar las lineas
que actualizan el progressbar y el label,
y casi que deberia tener la misma eficiencia
que el original (5 seg si no mal recuerdo)

En fin hacete unas pruebas y luego si queres cometalas.

Gracias.
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida