¿Alguna solución a la excepción de operación ilegal de hilos cruzados?

votos
15

Cuando los datos se vinculan en C #, el hilo que cambia los datos hace que el control también cambie. Pero si este subproceso no es en el que se creó el control, obtendrá una excepción de Operación de subproceso cruzado ilegal.

¿Hay alguna forma de prevenir esto?

Publicado el 05/08/2008 a las 08:45
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
3

Debería poder hacer algo como:

if (control.InvokeRequired)
{
    control.Invoke(delegateWithMyCode);
}
else
{
    delegateWithMyCode();
}

InvokeRequired es una propiedad de los controles para ver si está en el hilo correcto, luego Invoke invocará al delegado en el hilo correcto.

ACTUALIZACIÓN: En realidad, en mi último trabajo hicimos algo como esto:

private void SomeEventHandler(Object someParam)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new SomeEventHandlerDelegate(SomeEventHandler), someParam);
    }

    // Regular handling code
}

que elimina la necesidad del bloque else y ajusta el código.

Respondida el 05/08/2008 a las 08:51
fuente por usuario

votos
1

Como no tengo un caso de prueba para pasar, no puedo garantizar esta solución, pero me parece que sería adecuado un escenario similar al utilizado para actualizar las barras de progreso en diferentes subprocesos (usar un delegado).

public delegate void DataBindDelegate();
public DataBindDelegate BindData = new DataBindDelegate(DoDataBind);

public void DoDataBind()
{
    DataBind();
}

Si el enlace de datos debe hacerse por un hilo en particular, ¡entonces permita que ese hilo haga el trabajo!

Respondida el 05/08/2008 a las 08:56
fuente por usuario

votos
3

Si la modificación de los datos no consume demasiado tiempo (es decir, si el propósito principal del hilo de fondo no es la modificación real de los datos), intente mover la sección que modifica los datos a un delegado e invocar a ese delegado.

Si el trabajo pesado real está en los datos, probablemente tendrá que crear una copia profunda de estos datos para pasarlos al hilo de fondo, que enviará los datos procesados ​​de nuevo al hilo de la interfaz de usuario a través de Invocar nuevamente.

Solo tendrá que mover el código que cambia los datos a la función de delegado (porque el cambio de datos es lo que desencadena la actualización de control). Aparte de eso, no deberías tener que escribir nada extra.

Respondida el 05/08/2008 a las 09:05
fuente por usuario

votos
0

Si la conversación de subprocesos es "ilegal" (es decir, la llamada de DataBind afecta a los controles que no se crearon en el subproceso desde el que se está llamando), debe crear un delegado para que la decisión / preparación del DataBind no se realice en el hilo que crea el control, cualquier modificación resultante de ellos (es decir, DataBind ()) será.

Llamarías a mi código del hilo de trabajo así:

this.BindData.Invoke();

Esto haría que el hilo original hiciera el enlace, lo que (suponiendo que sea el hilo que creó los controles) debería funcionar.

Respondida el 05/08/2008 a las 09:06
fuente por usuario

votos
0

En WPF y Silverlight, la infraestructura de enlace se encarga de cambiar a la cadena de interfaz de usuario.

Respondida el 08/08/2008 a las 17:19
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more