Hola,
Leyendo este tema
http://foro.elhacker.net/net/iquesthacer_una_pausa_a_un_backgrounworker_en_vbnet-t405073.0.html;msg1906376
Me surge algunas dudas cuando trato de aplicarlo en mi proyecto.
Tengo un sub que verifica los procesos que estan corriendo en el Pc:
Tendría que quedar así supongo..
Private Sub MyWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) _
Handles MyWorker.DoWork
Do While MyWorker.CancellationPending = False
_busy.WaitOne(5000) 'Creo un intervalo de 5 segundos para ejecutar el Sub
CheckProcess()
Loop
e.Cancel = True
End Sub
Tengo otro sub que igual verifica los módulos de una aplicación que supongo tendria que hacer otro backgroundworker
¿Y cuál es la duda en concreto? Porque yo no he visto que hayas preguntado nada. Solamente, has puesto código, y lo has puesto mal.
Un saludo.
Pues busco saber si estoy por el camino correcto..
Si te distes cuenta modifique el código original porque necesito que el Loop no se detenga a menos que se haga true la cancelación...
Cita de: TrashAmbishion en 21 Agosto 2016, 18:59 PMnecesito que el Loop no se detenga a menos que se haga true la cancelación...
Si es una necesidad del tipo "hasta que..." en vez de "mientras que...", entonces puedes hacer el código algo más comprensible de la siguiente manera:
Do Until MyWorker.CancellationPending
...
Loop
Cita de: TrashAmbishion en 21 Agosto 2016, 18:50 PMMe surge algunas dudas cuando trato de aplicarlo en mi proyecto.
Para hacer una pausa (o dicho de otra forma: bloquear la ejecución del hilo actual) durante un intervalo definido (ej. 5 segundos) debes utilizar el método
System.Threading.Thread.Sleep():
Sleep(TimeSpan.FromSeconds(5))
CheckProcess()
El uso que le doy a la class
ManualResetEvent es para implementar una funcionalidad de pausar/continuar
a demanda o petición del usuario, puesto que el método
ManualResetEvent.WaitOne() sirve para bloquear la ejecución del thread durante un tiempo indefinido
hasta que se reciba una señal llamando a
ManualResetEvent.Set(), por eso si te fijas en mi ejemplo uso la constante de tiempo infinito
System.Threading.Timeout.Infinite.
Si tu especificas
5000 ms en el parámetro del método
ManualResetEvent.WaitOne(), con eso le estás diciendo que el hilo debe esperar hasta que transcurra ese intervalo de tiempo definido o hasta recibir una señal durante ese tiempo, y si no recibe una señal durante ese tiempo se resumirá el hilo, esto quiere decir que le estás dando la misma funcionalidad que si utilizases el método
System.Threading.Thread.Sleep(), pero no debes hacerlo, primeramente por que es innecesario, segundo por que es de buena costumbre utilizar el método más apropiado para "X" finalidad y en este caso el método
System.Threading.Thread.Sleep() es el que ha sido diseñado para dicha finalidad, y tercero por que podría ocasionarte un comportamiento indebido por culpa de un fallo de lógica humana, por ejemplo si enviases una señal en otra parte del código durante ese intervalo de tiempo.
Cita de: TrashAmbishion en 21 Agosto 2016, 18:50 PMTengo otro sub que igual verifica los módulos de una aplicación que supongo tendria que hacer otro backgroundworker
Depende del propósito del código, pero ya estás corriendo la tarea de la "verificación de procesos" en un hilo secundario ...puedes llevar a cabo la "verificación de módulos" de forma sincrónica si eso no te suponiese inconvenientes.
Saludos!
Gracias aclarada la duda es que en aquel tema pusiste el ejemplo pero no tenia bien claro el funcionamiento de esa función por el tema de los señales que me tenían inquieto..
Ok voy acomodarlo en el mismo Sub para ver como rula..
Una duda en el Form principal tengo 2 objetos un txt y un combo, para consultar el contenido de ambos desde una clase yo lo hacía:
frmprincipal.txtusername.text
Lo ideal seria que guardase estos valores en una clase que contenga esos parametros, cierto ?
Cita de: TrashAmbishion en 21 Agosto 2016, 20:37 PMUna duda en el Form principal tengo 2 objetos un txt y un combo, para consultar el contenido de ambos desde una clase yo lo hacía:
frmprincipal.txtusername.text
Lo ideal seria que guardase estos valores en una clase que contenga esos parametros, cierto ?
No se si he llegado a entender bien lo que quieres conseguir, pero si tienes un TextBox que muestra unos datos los cuales luego necesitas leer desde otra class, entonces puedes seguir haciendo eso.
Si necesitases evitar conflictos entre threads entonces también podrías declarar una variable compartida y asignarle el valor cada vez que se modifica el texto del TextBox:
Class Class1
Friend Shared Username As String
Friend TextBox1_TextChanged(sender As Object, e As Eventargs) Handles TextBox1.TextChanged
Class1.Username = DirectCast(sender, TextBox).Text
End Sub
End Class1
Class Class2
...
MsgBox(Class1.Usrname)
...
End Class2
Si necesitases leer múltiples objetos/valores desde la otra class, entonces definir un tipo personalizado para almacenar esos datos como tu dijiste sería ideal. También podrías serializar el tipo/clase en un archivo local.
Saludos
Ok lo tendré en cuenta, se me pasaba otra duda...
En el funcionamiento del Sub existirá el momento en que por ejemplo los modulos incrementen o se produzca un error y quisiera manejarlo...
Esto tendria que hacerlo con un raiseevent cierto ??
Salu2
Cita de: TrashAmbishion en 21 Agosto 2016, 21:03 PMEn el funcionamiento del Sub existirá el momento en que por ejemplo los modulos incrementen o se produzca un error y quisiera manejarlo...
Esto tendria que hacerlo con un raiseevent cierto ??
Los errores se controlan con bloques
try/catch:
Declaración de objetos...
Try
Instanciación de objetos...
Sentencias de procesos/modulos...
Catch ex As (Tipo De Excepción) ' When (Condición)
Informar de ex.Message
Finally
Liberación de objetos declarados.
End Try
( el bloque
Finally es opcional en caso de que no uses objetos "
disposables" )
Ahora, suponiendo que hayas declarado un evento en tu código entonces por supuesto puedes disparar ese evento con
RaiseEvent cuando controles un error ...pero yo diría que no es lo que realmente preguntas.
Saludos
Hola,
Por suerte se del Try y lo uso en casi todos los procedimientos y funciones a menos que sea algo muy simple.
Me explico mejor, en el Form principal tengo esta declaración:
Dim WithEvents Client_Conn as Winsock
Lo que pretendía en la clase BackgroundWorker era que cuando se produjera un error específico, este lo manejara usando el evento Enviar de e Client_Conn
Lo resolví
FormPrinc.Client_Conn.Enviar("Mensaje")
Esto lo hice por lo que me habías dicho anteriormente...
Cuando no debo usar esta forma...
Esto es aparte cuando yo llamo al Sub Cancel del Worker, en el DoWork se debe hacer TRUE el CancellationPending...
Class Class1
Friend Shared Username As String
Friend TextBox1_TextChanged(sender As Object, e As Eventargs) Handles TextBox1.TextChanged
Class1.Username = DirectCast(sender, TextBox).Text
End Sub
End Class1
Esto sería en el Form principal o en la clase donde voy a guardar los valores de esos Text, lo digo por el evento Text_Changed que asumo deba estar en el Form principal...
Salu2