¿Cómo escribir eventos de control para usarlos en múltiples subprocesos?
El método correcto es encapsular el código involucrado en la actualización de la interfaz en el hilo de trabajo en un método llamado a través de Invoke o BeginInvoke
La diferencia entre los dos es que un método causará el hilo de trabajo debe esperar, mientras que el otro método no lo hace.
Frame Framework WinForm Al crear una interfaz de programa GUI, si desea cambiar el estado del control en la función de respuesta al evento
, por ejemplo: se llama al texto de un botón avance para abrir, haga clic en el botón Después de que el texto se muestra burlonamente cerrado, los principiantes a menudo suponen que está escrito así:
void ButtonOnClick(object sender,EventArgs e)
{
button. Text="Close";
}
Después de ejecutar el programa de esta manera, se puede activar una excepción con un mensaje como " No puede recuperar el control de un hilo que no lo creó." Llame al control en ". El mensaje de excepción dice algo así como "No se puede llamar al control desde un hilo que nunca creó el control". Tenga en cuenta que esto es posible pero no necesariamente generará una excepción.
Esta excepción ocurre porque el control se crea en el hilo principal (por ejemplo, this.Controls.Add(.....)). Controls.Add(...);), y se accede a la función de respuesta a eventos del control en el hilo donde se encuentra el control
, no en el hilo principal. Cambiar el estado de un control dentro de la función de respuesta a eventos de un control puede causar un conflicto de subproceso con el subproceso principal. Si el hilo principal está volviendo a dibujar la apariencia del control, cambiar la apariencia del control en otro hilo causará confusión. Sin embargo, esto no siempre sucede si el hilo principal está volviendo a dibujar otro control en este momento, puede escapar y esta escritura no desencadenará una excepción.
El método correcto es llamar al método Invoke del control en la función de respuesta del control (de hecho, si ha usado C++ antes
Builder, encontrará que hay una función similar Invocar se puede activar en el hilo principal), esta función busca en el árbol de control hasta encontrar el hilo que creó el control (generalmente el hilo principal), y luego ingresa a ese hilo para cambiar el control (si ha usado C++ antes ) Builder, encontrará que hay una función similar a Invoke que se puede activar en el hilo principal), y luego ingrese al hilo para cambiar el control (si ha usado C++
Builder antes, Encontrará que hay una función similar a Invoke que se puede activar en el hilo principal).
Durante este proceso, verá un hilo (generalmente el hilo principal) e ingresará a ese hilo para cambiar la apariencia del control, asegurándose de que no haya conflictos de hilos.
La llamada operación de respuesta provocativa en un lado y agregar nodos en el otro lado solo puede ser relativa, por lo que la carga sobre el hilo de la interfaz de usuario no será demasiado grande, porque la actualización adecuada de la interfaz siempre lo debe hacer la interfaz de usuario
p>
El hilo está completo, y lo que tenemos que hacer es completar la mayoría de los cálculos en el hilo de trabajo y colocar las actualizaciones puras de la interfaz en el Hilo de interfaz de usuario, para que podamos lograr el objetivo de
y al mismo tiempo también pueda lograr el objetivo de reducir la carga sobre el hilo de interfaz de usuario
.
Para dar un ejemplo simple de cómo usar este método, digamos que está iniciando un hilo y desea actualizar un cuadro de texto en un formulario en un método de ese hilo.
Usar System.Threading;
/Iniciar un hilo
Thread thread=new Thread(new
ThreadStart(DoWork));
thread.
//Método de thread
private void DoWork()
{
this.TextBox1 .Text="Soy un TextBox";
}
Si opera de acuerdo con el método anterior, se producirá una excepción en VS2005 o 2008...
El enfoque correcto es usar Invoke\BeginInvoke
usando System.Threading;
prueba de espacio de nombres
{
público parcial clase Form1: Formulario
{
delegado público void MyInvoke(string str1,string str2);
formulario público1()
{
InitializeComponent();
}
public void DoWork()
{
MyInvoke mi = nuevo MyInvoke(UpdateForm) ;
this.BeginInvoke(mi);
this.BeginInvoke(mi);
this.BeginInvoke(mi)Texto = param1+ parm2;
p>
}
botón de anulación privada1_Click(remitente del objeto, EventArgs e)
{
Hilo = nuevo hilo(nuevo ThreadStart(DoWork)) ;
thread.Start();
}
}
}