Explicamos con un ejemplo cómo implementar la ejecución de un proceso o tarea en segundo plano con el lenguaje de programación Microsoft Visual Basic .Net 2010. Mostramos el código fuente source code de una aplicación de ejemplo que ejecuta un proceso en segundo plano con barra de progreso usando el componente BackgroundWorker.
- Hilo de ejecución, Threads.
- Componente BackgroundWorker en Visual Basic .Net VB.Net.
- Diseño del formulario Microsoft Visual Basic .Net VB.Net.
- Desarrollar aplicación con subproceso en segundo plano o asíncrono con Visual Basic .Net.
- Código fuente source code completo de aplicación con thread o hilo asíncrono con Visual Basic .Net VB.Net.
- La aplicación AjpdSoft Proceso segundo plano con progreso VB.Net en funcionamiento.
- Artículos relacionados.
- Créditos.
Hilo de ejecución, Threads
Un hilo de ejecución o subproceso es una característica que permite a una aplicación realizar varias tareas a la vez (concurrentemente). Los distintos hilos de ejecución comparten una serie de recursos tales como el espacio de memoria, los archivos abiertos, situación de autenticación, etc. Esta técnica permite simplificar el diseño de una aplicación que debe llevar a cabo distintas funciones simultáneamente.
Un hilo es básicamente una tarea que puede ser ejecutada en paralelo con otra tarea.
Los hilos de ejecución que comparten los mismos recursos, sumados a estos recursos, son en conjunto conocidos como un proceso. El hecho de que los hilos de ejecución de un mismo proceso compartan los recursos hace que cualquiera de estos hilos pueda modificar éstos. Cuando un hilo modifica un dato en la memoria, los otros hilos acceden a ese dato modificado inmediatamente.
Lo que es propio de cada hilo es el contador de programa, la pila de ejecución y el estado de la CPU (incluyendo el valor de los registros).
El proceso sigue en ejecución mientras al menos uno de sus hilos de ejecución siga activo. Cuando el proceso finaliza, todos sus hilos de ejecución también han terminado. Asimismo en el momento en el que todos los hilos de ejecución finalizan, el proceso no existe más y todos sus recursos son liberados.
Componente BackgroundWorker en Visual Basic .Net VB.Net
El componente BackgroundWorker permite que el formulario o control ejecute operaciones de forma asincrónica. Proporciona la posibilidad de ejecutar operaciones que llevan mucho tiempo de forma asincrónica ("en segundo plano"), en un subproceso distinto del subproceso de la IU principal de la aplicación.
La clase BackgroundWorker permite ejecutar una operación en un subproceso dedicado e independiente. Durante la ejecución de operaciones que exigen mucho tiempo, como las descargas y las transacciones de las bases de datos, puede parecer que la interfaz de usuario (UI) ha dejado de responder. Cuando se necesita una interfaz de usuario rápida, pero se producen largos retrasos asociados a tales operaciones, la clase BackgroundWorker ofrece una práctica solución.
Para ejecutar en segundo plano una operación que exija mucho tiempo, cree un objeto BackgroundWorker y realice escuchas de eventos que creen informes del progreso de la operación y que señalen su finalización. Se puede crear BackgroundWorker mediante programación o arrastrarlo al formulario desde la ficha Componentes del Cuadro de herramientas. Si crea BackgroundWorker en el Diseñador de Windows Forms, aparecerá en la Bandeja de componentes y sus propiedades se mostrarán en la ventana Propiedades.
Diseño del formulario Microsoft Visual Basic .Net VB.Net
Para el formulario de ejemplo de uso del componente BackgroundWorker (en el formulario llamado "hiloSegundoPlano") añadiremos los siguientes componentes:
- NumericUpDown: para establecer el número de iteraciones de la función de Fibonacci que será la usada en el ejemplo para realizar un cálculo que tarde un tiempo determinado y así probar el proceso en segundo plano.
- Label: mostrará el estado de la tarea ejecutada en segundo plano o background.
- ProgressBar: barra de progreso que mostrará el porcejate completado de la tarea en segundo plano.
- Button: botón para iniciar el proceso en segundo plano.
- Button: botón para cancelar el proceso en segundo plano ejecutado.
- TextBox: donde el usuario podrá escribir para comprobar que el proceso en segundo plano se está ejecutando y se puede, a su vez, interactuar con el formulario.
- Button: para limpiar el contenido del TextBox anterior.
- Button: para guardar el contenido del TextBox anterior, incluso aunque se esté ejecutando el proceso en segundo plano.
- BackgroundWorker: componente para generar el hilo o proceso en segundo plano, asíncrono o background.
- SaveFileDialog: componente para mostrar una ventana de petición de unidad, carpeta y nombre del fichero a guardar.
Estableceremos a True las propiedades WorkerReportsProgress y WorkerSupportsCancellation del componente BackgroundWorker:
Desarrollar aplicación con subproceso en segundo plano o asíncrono con Visual Basic .Net
En primer lugar crearemos un proyecto basado en Windows, desde el menú "Archivo" - "Nuevo proyecto", seleccionando "Aplicación de Windows Forms". Añadiremos los componentes que indicamos aquí al formluario principal de la aplicación.
Crearemos el procedimiento o función que será la que realice la acción que queramos ejecutar en proceso en segundo plano. Es importante mencionar que en dicho procedimiento o función no se puede hacer referencia a controles del formulario. Por ejemplo, si queremos mostrar una barra de progreso con el estado de la tarea, deberemos hacer referencia a la barra de progreso en el evento ProgressChanged del componente BackgroundWorker, si intentamos hacer una referencia a algún componente del formulario desde el procedimiento o función se producirá un error.
Añadiremos dicho procedimiento, en nuestro caso un ejemplo de cálculo de la Sucesión de Fibonacci:
Function CalcularFibonacci(ByVal n As Integer, ByVal worker As BackgroundWorker, ByVal e As DoWorkEventArgs) As Long 'No permitimos valores superiores a 91 ni inferiores a 9 If n < 0 OrElse n > 91 Then Throw New ArgumentException( _ "value must be >= 0 and <= 91", "n") End If Dim result As Long = 0 iteraciones = iteraciones + 1 'Si el usuario ha pulsado el botón cancelar abortar la operación If worker.CancellationPending Then e.Cancel = True Else If n < 2 Then result = 1 Else result = CalcularFibonacci(n - 1, worker, e) + _ CalcularFibonacci(n - 2, worker, e) End If 'Establecemos el % de progreso realizado del total de la tarea Dim percentComplete As Integer = _ CSng(n) / CSng(numberToCompute) * 100 If percentComplete > highestPercentageReached Then highestPercentageReached = percentComplete worker.ReportProgress(percentComplete) End If End If Return result End Function
En la función anterior hemos incluido las líneas de código:
Para controlar si el usuario ha pulsado el botón cancelar, de esta forma cancelaremos el proceso en segundo plano.If worker.CancellationPending Then e.Cancel = True Else ....
También la línea:
worker.ReportProgress(percentComplete)
Para devolver el porcentaje actual del progreso.
Como se puede observar en el código de la función, nunca se hace referencia a un componente del formulario.
Por otro lado en el evento DoWork del componente BackgroundWorker, agregaremos una llamada al método CalcularFibonacci:
Private Sub hiloSegundoPlano_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) _ Handles hiloSegundoPlano.DoWork 'Obtener el objeto BackgroundWorker que provocó este evento Dim worker As BackgroundWorker = CType(sender, BackgroundWorker) 'Asignar el resultado de la computación a la propiedad Result 'del objeto DoWorkEventArgs e.Result = CalcularFibonacci(e.Argument, worker, e) End Sub
En el procedimiento anterior (DoWork) ejecutaremos la función CalcularFibonacci pasándole varios parámetros para permtir la cancelación del proceso y para mostrar la información del progreso.
Es importante que el controlador de eventos DoWork no haga referencia directamente a la variable de la instancia BackgroundWorker (en el ejemplo llamado "hiloSegundoPlano"), ya que esto uniría este controlador de eventos a una instancia específica de BackgroundWorker. En su lugar, se recupera del parámetro sender una referencia al control BackgroundWorker que provocó este evento. Esto es importante cuando el formulario aloje más de un BackgroundWorker.
Para implementar la información de progreso, declaremos tres variables en el formulario formProceso. Éstas se utilizarán para realizar el seguimiento del progreso:
Public Class formProceso Private numeroSeriesFib As Integer = 0 Private highestPercentageReached As Integer = 0 Private iteraciones As Integer
En el evento ProgressChanged del componente BackgroundWorker añadiremos el siguiente código:
Private Sub hiloSegundoPlano_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) _ Handles hiloSegundoPlano.ProgressChanged barraProgreso.Value = e.ProgressPercentage lInfo.Text = "Iteraciones Fibonacci: " & CStr(iteraciones) End Sub
Para permitir que el usuario pueda cancelar el proceso en segundo plano, en el evento OnClick del botón btCancelarProceso introduciremos el siguiente código:
Private Sub btCancelarProceso_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btCancelarProceso.Click 'Cancelar proceso asíncrono hiloSegundoPlano.CancelAsync() 'Deshabilitar el botón cancelar btCancelarProceso.Enabled = False End Sub
Con estos procedimientos habremos conseguido ejecutar la función deseada (CalcularFibonacci) que puede realizar cualquier acción en segundo plano, de forma que de cara al usuario la función o procedimiento se ejecutará "sin que se entere" (si así lo deseamos). Podrá seguir interacturando con nuestra aplicación mientras se ejecuta la tarea en segundo plano. Este método es muy útil para determinados procesos donde consideremos que el usuario ni tiene que interactuar, mejorando así el rendimiento de nuestra aplicación.
Código fuente source code completo de aplicación con thread o hilo asíncrono con Visual Basic .Net VB.Net
A continuación mostramos el código fuente complento en Microsoft Visual Basic .Net de Microsoft Visual Studio 2010 como ejemplo de ejecución de tareas en segundo plano o asíncronas, con barra de progreso:
Imports System Imports System.Threading Imports System.Collections Imports System.ComponentModel Imports System.Drawing Imports System.Windows.Forms Imports System.IO Public Class formProceso Private numeroSeriesFib As Integer = 0 Private iteraciones As Integer Private porcentajeMasAlto As Integer = 0 Function CalcularFibonacci(ByVal n As Integer, ByVal worker As BackgroundWorker, ByVal e As DoWorkEventArgs) As Long 'No permitimos valores superiores a 91 ni inferiores a 9 If n < 0 OrElse n > 91 Then Throw New ArgumentException( _ "value must be >= 0 and <= 91", "n") End If Dim result As Long = 0 iteraciones = iteraciones + 1 'Si el usuario ha pulsado el botón cancelar abortar la operación If worker.CancellationPending Then e.Cancel = True Else If n < 2 Then result = 1 Else result = CalcularFibonacci(n - 1, worker, e) + _ CalcularFibonacci(n - 2, worker, e) End If 'Establecemos el % de progreso realizado del total de la tarea Dim porcentajeCompletado As Integer porcentajeCompletado = CSng(n) / CSng(numeroSeriesFib) * 100 If porcentajeCompletado > porcentajeMasAlto Then porcentajeMasAlto = porcentajeCompletado worker.ReportProgress(porcentajeCompletado) End If End If Return result End Function Private Sub btIniciarProceso_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btIniciarProceso.Click iteraciones = 0 barraProgreso.Minimum = 0 barraProgreso.Maximum = 100 lInfo.Text = [String].Empty 'Deshabilitamos el ListBox con el número de iteraciones 'hasta que concluya el proceso txtNumeroIteraciones.Enabled = False 'Deshabilitar el botón de inicio de proceso 'hasta que el proceso asíncrono haya concluido btIniciarProceso.Enabled = False 'Habilitamos el botón cancelar 'mientras la operación está ejecutándose btCancelarProceso.Enabled = True 'Obtenemos el valor de iteraciones seleccionado por el usuario numeroSeriesFib = CInt(txtNumeroIteraciones.Value) 'Iniciamos el valor de la variable que contendrá el % del progreso porcentajeMasAlto = 0 'Iniciamos el proceso asíncrono en segundo plano hiloSegundoPlano.RunWorkerAsync(numeroSeriesFib) End Sub Private Sub btLimpiar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btLimpiar.Click txtTexto.Text = [String].Empty End Sub Private Sub btGuardar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btGuardar.Click dlGuardar.Filter = "Archivos de texto (*.txt)|*.txt|Todos (*.*)|*.*" dlGuardar.FilterIndex = 1 dlGuardar.DefaultExt = "txt" dlGuardar.FileName = "texto" dlGuardar.OverwritePrompt = True dlGuardar.Title = "Guardar fichero mientras se ejecuta tarea en segundo plano" If dlGuardar.ShowDialog Then Try Dim fichero As New StreamWriter(dlGuardar.FileName) fichero.WriteLine(txtTexto.Text) fichero.Close() Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.OkOnly + _ MsgBoxStyle.Exclamation) End Try End If End Sub Private Sub hiloSegundoPlano_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) _ Handles hiloSegundoPlano.DoWork 'Obtener el objeto BackgroundWorker que provocó este evento Dim worker As BackgroundWorker = CType(sender, BackgroundWorker) 'Asignar el resultado de la computación a la propiedad Result 'del objeto DoWorkEventArgs e.Result = CalcularFibonacci(e.Argument, worker, e) End Sub Private Sub hiloSegundoPlano_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) _ Handles hiloSegundoPlano.ProgressChanged barraProgreso.Value = e.ProgressPercentage lInfo.Text = "Iteraciones Fibonacci: " & CStr(iteraciones) End Sub Private Sub hiloSegundoPlano_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _ Handles hiloSegundoPlano.RunWorkerCompleted 'Manejar el caso en que se produzca un error o excepción If (e.Error IsNot Nothing) Then MsgBox(e.Error.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical) Else If e.Cancelled Then 'Manejar el caso en que el usuario haya cancelado la operación. lInfo.Text = "Proceso cancelado" Else 'Manejar el caso en que la operación haya finalizado con éxito lInfo.Text = e.Result.ToString() End If End If 'Habilitamos el ListBox del número de iteraciones txtNumeroIteraciones.Enabled = True 'Habilitamos el botón de iniciar proceso btIniciarProceso.Enabled = True 'Deshabilitamos el botón cancelar btCancelarProceso.Enabled = False End Sub Private Sub btCancelarProceso_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btCancelarProceso.Click 'Cancelar proceso asíncrono hiloSegundoPlano.CancelAsync() 'Deshabilitar el botón cancelar btCancelarProceso.Enabled = False End Sub End Class
La aplicación AjpdSoft Proceso segundo plano con progreso VB.Net en funcionamiento
Tras seleccionar el número de iteraciones y pulsar en "Iniciar proceso asíncrono" se iniciará el proceso, mostrará la barra de progreso y se activará el botón "Cancelar proceso asíncrono". Si queremos probar que el proceso se ejecuta en segundo plano realmente y que podemos interactuar con la aplicación, podremos escribir en el cuadro de texto y guardar los cambios mientras el proceso se está ejecutando:
Si eres desarrollador de software y quieres descargar el ejemplo complento en Microsoft Visual Basic .Net 2010 regístrate en nuestra web y accede al enlace:
Artículos relacionados
- Instalar Visual Studio 2010 y desarrollar aplicación con acceso a PostgreSQL.
- El control de errores en Visual Basic .Net.
- Acceso a MySQL mediante Visual Basic .Net y ODBC.
- Acceso a Oracle mediante Microsoft Visual Basic, RDO y ODBC.
- Insertar y extraer documentos en una tabla Oracle con Visual Basic 6.
- Artículos, manuales y trucos del Proyecto AjpdSoft sobre Microsoft Visual Studio.
- Instalar el motor de bases de datos PostgreSQL en GNU Linux Debian 5.
- Instalar y administrar PostgreSQL en Microsoft Windows 7.
- Instalar el motor de base de datos PostgreSQL 8.4 en GNU Linux Ubuntu 10.
- Ejercicios resueltos en el lenguje de programación C.
- Artículos del Proyecto AjpdSoft sobre sistemas operativos (Windows, GNU Linux, etc.).
- Artículos del Proyecto AjpdSoft sobre los sistemas operativos Microsoft Windows.
- Artículos del Proyecto AjpdSoft sobre Delphi (lenguaje de programación).
- Artículos del proyecto AjpdSoft sobre Java (lenguaje de programación).
- AjpdSoft Conexión BD Visual Basic .Net.
- Todos los programas con código fuente en Visual Basic.
No hay comentarios:
Publicar un comentario