2011-02-18 21 views
25

Possible Duplicate:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created onoperación de la Cruz-hilo no válida

bien, sé por qué esto me está dando este error:

Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.

Pero ... ¿Cómo puedo hacer que esto funcione?

System.Threading.Thread t = new System.Threading.Thread(()=> 
{ 
    // do really hard work and then... 
    listView1.Items.Add(lots of items); 
    lots more UI work 
}); 
t.Start(); 

No me importa cuándo o cómo los acabados de rosca, por lo que realmente no importa nada de fantasía o más complicada atm, a no ser que va a hacer las cosas mucho más fácil cuando se trabaja con la interfaz de usuario en una nuevo hilo.

+0

+1 @blue , sí, parece que hay una clase entera de preguntas similares con respecto a esto, todas formuladas de una manera ligeramente diferente pero con la misma idea central de que las operaciones de IU deben realizarse en el mismo hilo. – Joe

+0

Esto se ha preguntado muchas veces antes. Mira esto: http://stackoverflow.com/questions/1523878/cross-thread-operation-not-valid-in-c o http://stackoverflow.com/questions/1485786/error-cross-thread-operation- no válido o http://stackoverflow.com/questions/1377529/cross-thread-operation-not-valid o http://stackoverflow.com/questions/1397370/cross-thread-operation-not-valid-in- c o http://stackoverflow.com/questions/4010602/c-cross-thread-operation-not-valid o http://stackoverflow.com/questions/3439065/cross-thread-operation-not-valid-in- c – Joe

Respuesta

22

No puede. Las operaciones de la interfaz de usuario se deben realizar en el hilo propietario. Período.

Lo que podría hacer, es crear todos esos elementos en un hilo secundario, luego llamar al Control.Invoke y hacer allí su enlace de datos.

O utilizar un BackgroundWorker

BackgroundWorker bw = new BackgroundWorker(); 
    bw.DoWork += (s, e) => { /* create items */ }; 
    bw.RunWorkerCompleted += (s, e) => { /* databind UI element*/ }; 

    bw.RunWorkerAsync(); 
+1

Ah, genial. Muchas gracias @ Adam. –

+0

Respuesta sólida, pero tengo curiosidad sobre por qué "No se puede" es cierto. ¿Tienes alguna otra lectura? – Matt

13

Al acceder a la propiedad de partir desde otro hilo, se lanza esta excepción. Para solucionar este problema, hay al menos 2 opciones.

  1. Telling control para no arrojo estas excepciones (que no se recomienda):

    Control.CheckForIllegalCrossThreadCalls = false;

  2. Usando hebras funciones:

    private void ThreadSafeFunction(int intVal, bool boolVal) 
    { 
        if (this.InvokeRequired) 
        { 
         this.Invoke(
          new MethodInvoker(
          delegate() { ThreadSafeFunction(intVal, boolVal); })); 
        } 
        else 
        { 
         //use intval and boolval 
        } 
    } 
    
Cuestiones relacionadas