Gracias los dos
No estoy seguro que opción es mejor pero creo que por sencillez me decanto por usar la variable boleana.
He aprovechado para realizar un experimento de velocidad de los procesos dentro del bucle, para este ejemplo, que imagino que según el ordenador los resultados será distinto.
Option Explicit On
Option Strict On
Imports System.Text
Public Class Form1
Dim AplicacionCerrada As Boolean = False
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim stopWatch As New Stopwatch() : Dim ts As TimeSpan : Dim elapsedTime As String = Nothing
Dim Cont As Integer = 0
stopWatch.Start()
Do
Cont += 1
ts = stopWatch.Elapsed
String.Format("{00}", ts.Seconds)
'///Experimeto que mide el número de procesos por segundo
Dim Datos As New StringBuilder
With Datos
.AppendFormat("Procesos: {0}", CInt(Cont))
.AppendLine()
.AppendFormat("Segundos: {0}", ts.Seconds)
.AppendLine()
.AppendFormat("Velocidad: {0}", (CInt(Cont) / (CInt(ts.Seconds))).ToString("0.000") & " Proc/s")
End With
Label1.Text = Datos.ToString
'/////////////////////////////////////////////////////////////////////////
If AplicacionCerrada = True Then End
If ts.Seconds = 10 Then stopWatch.Stop() : Exit Do
My.Application.DoEvents()
Loop While Cont < 14000
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles MyBase.FormClosing
AplicacionCerrada = True
End Sub
End Class
Esta sería la otra forma, aunque más compleja y que me ha costado encontrar.
Option Explicit On
Option Strict On
Imports System.Threading.Tasks
Imports System.Text
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim stopWatch As New Stopwatch() : Dim ts As TimeSpan : Dim elapsedTime As String = Nothing
Dim Cont As Integer = 0
Task.Factory.StartNew(Sub()
stopWatch.Start()
'Desactivar el chequeo sobre acceso de varios subprocesos
' CheckForIllegalCrossThreadCalls = False
Do
Cont += 1
ts = stopWatch.Elapsed
String.Format("{00}", ts.Seconds)
'///Experimeto que mide el número de procesos por segundo
Dim Datos As New StringBuilder
With Datos
.AppendFormat("Procesos: {0}", CInt(Cont))
.AppendLine()
.AppendFormat("Segundos: {0}", ts.Seconds)
.AppendLine()
.AppendFormat("Velocidad: {0}", (CInt(Cont) / (CInt(ts.Seconds))).ToString("0.000") & " Proc/s")
End With
Label1.Invoke(CType(Sub() Label1.Text = Datos.ToString, MethodInvoker))
'/////////////////////////////////////////////////////////////////////////
If ts.Seconds = 10 Then stopWatch.Stop() : Exit Do
' My.Application.DoEvents()
Loop While Cont < 14000
End Sub).ContinueWith(Sub()
Me.Invoke(Sub()
Me.Text = "Proceso terminado"
End Sub)
End Sub)
End Sub
End Class
De esta última forma usando Task e Invoke como habéis dicho el programa se cierra sin problemas.
Me ha costado averiguar también como llamar a un control externo dentro de un subproceso, ya que si llamaba diréctamente obtenía error. La forma era la siguiente:
Label1.Invoke(DirectCast(Sub() Label1.Text = Datos, MethodInvoker))
También:
Me.Invoke(Sub()
Me.Text = "Proceso terminado"
End Sub)
En cuanto a la eficiencia creo que es lo mismo porque me dan resultados idénticos, me refiero al experimento.
Si el ordenador es al menos normalito, debería salir del bucle antes de los 10 segundos.
Saludos