Estoy teniendo problemas con esto:
Thread_Split.Start()
While Not Thread_is_completed = True
Application.DoEvents()
End While
Cuando inicio el thread por segunda vez, me salta este error:
Arithmetic operation resulted in an overflow.
¿Porqué?
Pero el problema no se si esta ahi, el problema esta en el pedazo de codigo que no has puesto, donde realiza esa operacion como dice el error.
De todas formas, esta bien esa forma de usar DoEvents? si estas usando threads no seria necesario, creo yo.. que alguien me lo confirme.
Edu,
¿Como le harías tu?
La intención del código de arriba es esto:
Thread_Split.Start() ' Ejecutar el thread
' ( Al acabar el thread la variable booleana se vuelve TRUE )
Hasta que "Variable booleana" séa igual a "True"
No hacer nada de nada
End While
Si no encuentro solución pronto arreglaré un poco el thread para postearlo...
Gracias y Saludos.
¿Por que usas un thread?, si estas esperando a que el thread termine, ¿en que se diferenciaría de ejecutarlo en el "main"?
Saludos
Se diferencia en que la aplicación no se "cuelga" al usar un while + aplication.doevents() :-/
De alguna manera tengo que esperar hasta que el thread mande una respuesta como diciendo "he acabado mi trabajo", por ejemplo para cambiar el estado de un botón:
Botón con texto "Start" > inicia el thread > cambia el texto a "STOP"
hasta que el thread no acabe el texto del botón no vuelve a ser "Start".
¿Me entienden?
Application.DoEvents() es una instrucción propia de VB6 y ésto es .NET. No es recomendable emplear técnicas vb6 en VB.NET pues para algo tenemos el Framework.
Supongo que lo que quieres es que se ejecute un hilo y se detenga la ejecucción del código que sigue después de la llamada .Start() del hilo hasta que el Thread haya terminado su ejección.
Empleando la clase ManualResetEvent bloqueas la ejecucción del código hasta que el objeto que contiene la instancia de ManualResetEvent haya recibido una señal.
Ejemplo:
Dim manualEvent As New ManualResetEvent(False)
Private Sub ThreadProc(Byval Parametros As Object()) 'Pasamos todos los parametros por valor dentro de un Array de tipo Object
'Extraemos los parametros
'Ejecutamos las instrucciones de este método
'...
'Mandamos la señal a ManualEvent diciendole que siga con la ejecucción del programa
ManualEvent.Set()
End Sub
Private Sub EjecutarThread()
Dim t as new thread(AddressOf ThreadProc)
t.start(obj()) 'Le pasas al thread el array que contiene los parámetros
'Esperamos hasta que ManualEvent reciba la señal
ManualEvent.WaitOne()
MsgBox("Thread Completado")
End Sub
Gracias Kubox, luego intento hacer eso porque es un poco lío para mí xD
De todas formas creo que el problema no tiene nada que ver con el thread.
MsgBox(Thread_is_completed) ' el valor es False
Me da exactamente el mismo error que he comentado en el primer comentario... aritmetic bla bla bla...
Me he equivocado con eso.
¿Porqué? :(
Pero el error habla de una operacion aritmetica que se desborda, tienes que dejar el pedazo de codigo de tu thread
El código que te puse es para que veas como trabajando con señales puedes bloquear procesos y ponerlos a la espera de una señal. En cuanto a el error que obtienes, como dice $Edu$ se produce al tratar un tipo de dato no comprendido entre los límites establecidos de dicho tipo de dato. Por ejemplo el tipo de variable Integer soporta números comprendidos entre -2147483647 y +2147483647, si te salieras de ese límite se produciría el OverFlow.
Revisa el código del Thread en busca de posibles errores en los datos que almacenas en las distintas variables. Te recomiendo que Debuguees la aplicación para ver que valores van tomando éstas.
Saludos!
EDITO:
Ya lo he arreglado, era culpa de la maldita barra de progreso extendida y su propiedad "textshow",si le sumaba un valor sin que hubiera ningún valor que mostrar, da error".
Saludos!
Pues no, con lo de antes no me equivocaba, me salta error hasta por esto!:
Thread_Split.Start()
MsgBox("a")
El msgbox me salta error de operación aritmética, juas!!!! no lo entiendo...
Ahora mismo me encuentro tocando todo el thread para intentar solucionarlo, lo siento si no es muy bonito ni uso técnicas tán avanzadas como la que ha comentado Kubox xD...
Este es el botón que llama al thread, bueno, es un botón para llamarlo, y otro para abortarlo.
#Region " Button Split "
' Button SPLIT
Private Sub Button_Split_ClickButtonArea(Sender As Object, e As MouseEventArgs) Handles Button_Split.ClickButtonArea
'Try : Thread_Split.Abort() : Catch : End Try
Thread_is_completed = False
Thread_Split = New Threading.Thread(AddressOf Split_Thread)
Thread_Split.IsBackground = True
Thread_Split.Start()
MsgBox("a") ' esto da error cuando inicio el thread por segunda vez....juas...
While Not Thread_is_completed = True
Application.DoEvents()
End While
'Thread_is_completed = True
Want_to_cancel_thread = False
End Sub
' Button STOP
Private Sub Button_Stop_ClickButtonArea(Sender As Object, e As MouseEventArgs) Handles Button_Stop.ClickButtonArea
Want_to_cancel_thread = True
' Try : Thread_Split.Abort() : Catch : End Try
' Thread_is_completed = True
Kill_Process("7z")
Kill_Process("rar")
End Sub
#End Region
el thread:
#Region " Split Thread "
Sub Split_Thread()
TotalFiles_Number = 0
If Copy_Mode = "Copy" Or Copy_Mode = "Move" And Not Want_to_cancel_thread = True Then
If Not Want_to_cancel_thread = True Then
Get_All_Files(New IO.DirectoryInfo(Selected_Directory))
' ProgressBar
InvokeControl(ProgBarPlus, Sub(x) x.Max = TotalFiles_Number)
If Copy_Mode = "Copy" Then : InvokeControl(ProgBarPlus, Sub(x) x.TextFormat = "Copying {0} of {2} files")
ElseIf Copy_Mode = "Move" Then : InvokeControl(ProgBarPlus, Sub(x) x.TextFormat = "Moving {0} of {2} files")
End If
InvokeControl(ProgBarPlus, Sub(x) x.TextShow = ProgBar.ProgBarPlus.eTextShow.FormatString)
' Copy /Move
Dim FolderNum As Integer = 1
For Each File In Files_List
If Not Want_to_cancel_thread = True Then
Cached_Size += File.Split("|")(2)
If Not Cached_Size >= Selected_Disc_Bytes Then
If Copy_Mode = "Copy" Then Copy_File(File.Split("|")(0) & "\" & File.Split("|")(1), Selected_Output_Directory & "\Disc " & FolderNum & Get_File_Info(File.Split("|")(0) & "\" & File.Split("|")(1), DirectoryName).ToString.Split(":")(1), True, True)
'If Copy_Mode = "Move" Then Move_File(File.Split("|")(0) & "\" & File.Split("|")(1), Selected_Output_Directory & "\Disc " & FolderNum & Get_File_Info(File.Split("|")(0) & "\" & File.Split("|")(1), DirectoryName).ToString.Split(":")(1), True, True)
Else
Cached_Size = Nothing
FolderNum += 1
If Copy_Mode = "Copy" Then Copy_File(File.Split("|")(0) & "\" & File.Split("|")(1), Selected_Output_Directory & "\Disc " & FolderNum & Get_File_Info(File.Split("|")(0) & "\" & File.Split("|")(1), DirectoryName).ToString.Split(":")(1), True, True)
'If Copy_Mode = "Move" Then Move_File(File.Split("|")(0) & "\" & File.Split("|")(1), Selected_Output_Directory & "\Disc " & FolderNum & Get_File_Info(File.Split("|")(0) & "\" & File.Split("|")(1), DirectoryName).ToString.Split(":")(1), True, True)
End If
InvokeControl(ProgBarPlus, Sub(x) x.Value += 1)
Else
Want_to_cancel_thread = False
Thread_is_completed = True
'Try : Thread_Split.Abort() : Catch : End Try
Exit For
End If
Next
End If
ElseIf Copy_Mode = "7Zip" And Not Want_to_cancel_thread = True Then
InvokeControl(ProgBarPlus, Sub(x) x.TextFormat = "Progress is not avaliable for 7Zip")
InvokeControl(ProgBarPlus, Sub(x) x.TextShow = ProgBar.ProgBarPlus.eTextShow.FormatString)
Run_Process("7z.exe", " a " & """" & Selected_Output_Directory & "\Disc.7z" & """" & " " & """" & Selected_Directory & """" & " -v" & Selected_Disc_Bytes.ToString & "b " & " -m0=BCJ -bd -y", False, True)
ElseIf Copy_Mode = "Rar" And Not Want_to_cancel_thread = True Then
InvokeControl(ProgBarPlus, Sub(x) x.TextFormat = "Progress is not avaliable for Rar")
InvokeControl(ProgBarPlus, Sub(x) x.TextShow = ProgBar.ProgBarPlus.eTextShow.FormatString)
Run_Process("RAR.exe", " a " & """" & Selected_Output_Directory & "\Disc.rar" & """" & " " & """" & Selected_Directory & """" & " -v" & Selected_Disc_Bytes.ToString & "b " & " -m0 -ibck -o+", False, True)
ElseIf Copy_Mode = "Exe" And Not Want_to_cancel_thread = True Then
InvokeControl(ProgBarPlus, Sub(x) x.TextFormat = "Progress is not avaliable for Exe")
InvokeControl(ProgBarPlus, Sub(x) x.TextShow = ProgBar.ProgBarPlus.eTextShow.FormatString)
Run_Process("RAR.exe", " a -sfx " & """" & Selected_Output_Directory & "\Disc.exe" & """" & " " & """" & Selected_Directory & """" & " -v" & Selected_Disc_Bytes.ToString & "b " & " -m0 -ibck -o+", False, True)
End If
MessageBox.Show("All files compressed", "Splitty 1.2", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1)
Want_to_cancel_thread = False
Thread_is_completed = True
'Try : Thread_Split.Abort() : Catch : End Try
'Exit Sub
End Sub
#End Region
Cita de: EleKtro H@cker en 16 Enero 2013, 15:55 PM
Se diferencia en que la aplicación no se "cuelga" al usar un while + aplication.doevents() :-/
Con ese objetivo entonces si :P, aunque sigo insistiendo con el tema de los threads, ¿intentaste utilizar un
backgroundworker? Te provee de eventos como
RunWorkerCompleted :P
Saludos
Nov lo que pasa es que el backgroundworker me da mucho palo usarlo para hilos pequeños de menos de 50 líneas, porque si uso el BGW tengo que usar todos los subs que provee el BGW para que no me vengan posibles errores, dowork, reportprogress, y el resto, en fín son bastantes y es un coñazo xD.
En otra aplicación si que uso el backgroundworker porque el thread as grandísimo, pero aquí no me vale la pena, no lo domino y luego me acabo liando con tanta cosa.
Saludos!
El error debe estar en la ultima etiqueta de codigo que escribiste.