Un hilo se define como la ruta de ejecución de un programa. Cada hilo define un control de flujo único. Si su aplicación implica operaciones complejas y que requieren mucho tiempo, como acceso a bases de datos o algunas operaciones de E/S intensas, entonces suele ser muy beneficioso configurar diferentes rutas de ejecución o subprocesos, donde cada subproceso realiza un trabajo específico.
Los hilos son procesos livianos. Un ejemplo común del uso de subprocesos es la implementación de programación paralela en sistemas operativos modernos. El uso de subprocesos evita la pérdida de ciclos de CPU y mejora la eficiencia de las aplicaciones.
El programa que hemos compilado hasta ahora se ejecuta como un proceso único en un subproceso, que es la instancia en ejecución de la aplicación. Sin embargo, una aplicación de este tipo sólo puede realizar un trabajo a la vez. Para que realice varias tareas al mismo tiempo, puedes dividirlo en subprocesos más pequeños.
En .Net, los subprocesos se manejan a través del espacio de nombres 'System.Threading'. Crear variables de tipo system.threading.thread le permite crear un nuevo hilo para comenzar a trabajar. Le permite crear y acceder a hilos independientes en un hilo separado.
Un hilo se crea a partir de un objeto de hilo y su constructor recibe una referencia para iniciar el hilo.
ThreadStart childthreat = nuevo ThreadStart(childthreadcall);
El ciclo de vida de un subproceso comienza cuando se crea un objeto de la clase system.threading.thread y finaliza cuando el subproceso finaliza o se completa la ejecución.
Los siguientes son los distintos estados en el ciclo de vida de un hilo:
Estado de inicio pendiente: se ha creado la instancia del hilo pero no se ha llamado al método de inicio.
Estado listo: una situación en la que un subproceso está listo para ejecutarse y espera un ciclo de CPU.
Estado no ejecutable: cuando un hilo no se puede ejecutar, existen varias posibilidades:
El método de sueño actual se llama
El método de espera se llama
Bloqueado por operación de E/S
Estado de muerte: el hilo ha completado la ejecución o ha sido terminado.
El atributo de prioridad en la clase Thread especifica principalmente la prioridad de un hilo en relación con otros hilos. El tiempo de ejecución de .NET selecciona el subproceso listo con la mayor prioridad. La prioridad se puede dividir en:
más alto de lo normal
más bajo de lo normal
más alto
más bajo
normal
Una vez que se crea un hilo, el sistema establece su prioridad utilizando el sistema de configuración de prioridad de la clase Thread.
NewThread.Priority = ThreadPriority.Highest;
La clase de hilo tiene las siguientes características importantes:
propiedad | describir |
---|---|
Contexto actual | Obtenga el contenido del hilo que se está ejecutando actualmente. |
Cultura actual | Obtiene o establece el entorno del subproceso actual. |
Principio actual | Obtiene o establece la política de seguridad basada en roles del proceso actual. |
Hilo actual | Obtenga el hilo que se está ejecutando actualmente. |
Cultura actual de la UI | Obtiene o establece el entorno actual utilizado por el administrador de recursos del proceso actualmente en ejecución para buscar recursos específicos. |
Contexto de ejecución | Obtiene un objeto ExecutionContext que contiene información contextual sobre el hilo actual. |
Está vivo | Obtiene un valor que indica el estado de ejecución del subproceso actual. |
es fondo | Background Obtiene o establece un valor que indica si el subproceso es un subproceso en segundo plano. |
EsThreadPoolThread | Obtiene un valor que indica si el subproceso pertenece al grupo de subprocesos administrado. |
ID de hilo administrado | Obtiene el identificador único actual del subproceso administrado. |
Nombre | Obtiene o establece el nombre del hilo. |
Prioridad | Obtiene o establece un valor que indica la prioridad de programación de un subproceso. |
Estado del hilo | Obtiene un valor que contiene el estado del hilo actual. |
La clase de hilo tiene los siguientes métodos importantes:
método | describir |
---|---|
Abortar | Llamar a ThreadAbortException inicia el proceso de terminar el hilo. Llamar a este método generalmente termina el hilo. |
Asignar ranura de datos | A todos los subprocesos se les asigna una ranura de datos sin nombre. Para un mejor rendimiento, utilice los campos marcados con el atributo ThreadStaticAttribute. |
Asignar ranura de datos con nombre | Asigne espacios de datos con nombre a todos los subprocesos. Para un mejor rendimiento, utilice los campos marcados con el atributo ThreadStaticAttribute. |
ComenzarRegiónCrítica | Notifica al host que la ejecución está a punto de ingresar a una región de código donde los efectos de un aborto de subproceso o una excepción no controlada podrían comprometer otras tareas. |
ComenzarThreadAffinity | Notifica al host que el código administrado está a punto de ejecutarse, según la identidad del subproceso físico actual del sistema operativo. |
Región crítica final | Notifica al host que la ejecución está a punto de ingresar a una región de código donde un hilo cancelado o una excepción no controlada afecta solo a la tarea actual. |
EndThreadAfinidad | Notifica al host que la ejecución del código administrado se ha completado, según la identidad del subproceso físico actual del sistema operativo. |
Ranura de datos con nombre gratuito | Elimina la asociación entre nombres y espacios para todos los subprocesos del proceso. Para un mejor rendimiento, utilice los campos marcados con el atributo ThreadStaticAttribute. |
Obtener datos | Recupera un valor de la ranura especificada por el subproceso actual en el dominio actual del subproceso actual. Para un mejor rendimiento, utilice los campos marcados con el atributo ThreadStaticAttribute. |
Obtener dominio | Devuelve el hilo que se está ejecutando actualmente en el dominio actual. |
ObtenerID de dominio | Devuelve el identificador único del dominio de la aplicación. |
Obtener ranura de datos con nombre | Busque una ranura de datos con nombre. Para un mejor rendimiento, utilice los campos marcados con el atributo ThreadStaticAttribute. |
Interrumpir | Interrumpe un hilo en el estado de hilo WaitSleepJoin. |
Unirse | Bloquea el hilo de llamada hasta que uno de los hilos termina, mientras continúa la ejecución estándar de COM y SendMessage. Este método tiene diferentes formas sobrecargadas. |
Barrera de memoria | Los accesos a la memoria sincrónicos son los siguientes: el acelerador que procesa el hilo actual no puede reordenar las instrucciones de tal manera que el acceso a la memoria llame a MemoryBarrier seguido de la ejecución del acceso a la memoria. |
ReiniciarAbortar | Cancela la solicitud de cancelación del hilo actual. |
Establecer datos | Establece los datos para el subproceso en ejecución actual en el intervalo de tiempo especificado y el dominio actual de ese subproceso. Para un mejor rendimiento, el dominio de la aplicación tiene el atributo ThreadStaticAttribute del dominio. |
Comenzar | Iniciar un hilo. |
Dormir | Hace que el hilo se detenga por un período de tiempo. |
GirarEsperar | Hace que el hilo espere el número de iteraciones definidas por el parámetro. |
lectura volátil() | Lea el valor del campo. El último valor lo escribe cualquier procesador de la computadora, independientemente del procesador o del número de estado de caché del procesador. Este método tiene diferentes formas sobrecargadas. |
Escritura volátil() | Escribe inmediatamente un valor en un campo que es visible para todos los procesadores de la computadora. Este método tiene diferentes formas sobrecargadas. |
Producir | Hace que el subproceso que realiza la llamada ejecute otro subproceso que se puede ejecutar en el procesador actual y el sistema operativo elige redirigir el subproceso. |
El siguiente ejemplo ilustra el uso de clases de subprocesos. La página tiene una etiqueta de control que muestra mensajes de hilos secundarios. Los mensajes del programa principal se muestran directamente usando el método Response.write(50), por lo que aparecen en la parte superior de la página.
Los archivos fuente son los siguientes:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="threaddemo._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transicional// ES" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title> Página sin título </title> </head> <body> <form id="form1 " runat="servidor"> <div> <h3>Ejemplo de subproceso</h3> </div> <asp:Label ID="lblmessage" runat="servidor" Text="Label"> </asp:Label> < /formulario> </cuerpo> </html>
El código de fondo es el siguiente:
usando System.Collections; usando System.Configuration; usando System.Web.UI.HtmlControls; ; usando System.Web.UI.WebControls; usando System.Web.UI.WebControls.WebParts; usando System.Xml.Linq usando System.Threading; clase _Default: System.Web.UI.Page { protected void Page_Load(remitente del objeto, EventArgs e) { ThreadStart childthreat = new ThreadStart(childthreadcall Response.Write("Subproceso secundario iniciado <br/>"); Thread(childthreat); child.Start(); Response.Write("Duerme principal durante 2 segundos....<br/>"); Thread.Sleep(2000); Response.Write("<br/>Hilo hijo principal abortando<br/>"); child.Abort() } public void childthreadcall() { try{ lblmessage.Text = "<br/ >Subproceso secundario iniciado <br/>"; lblmessage.Text += "Subproceso secundario: Contando hasta 10"; for( int i =0; i<10; i++) { Thread.Sleep(500); lblmessage.Text += "<br/> en hilo secundario </br>" } lblmessage.Text += "<br/> hilo secundario terminado"; catch(ThreadAbortException e){ lblmessage.Text += "<br /> subproceso secundario - excepción" }finalmente{ lblmessage.Text += "<br /> subproceso secundario: no se puede detectar la excepción";
Cuando se carga la página, se inicia un nuevo hilo con childthreadcall() como referencia. Las actividades del hilo principal se mostrarán directamente en la página web.
Se ejecuta un segundo hilo y envía el mensaje a la etiqueta de control.
El subproceso principal duerme durante 2000 milisegundos mientras se ejecuta el subproceso secundario.
El subproceso secundario continúa ejecutándose hasta que el subproceso principal lo finaliza, luego lanza una ThreadAbortException y finaliza.
El control vuelve al hilo principal.
Cuando se ejecute el programa enviará la siguiente información: