2009-10-06 14 views
12

Possible Duplicate:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created onOttenere operazione cross-thread non valida

public void CheckUnusedTabs(string strTabToRemove) 
{ 
    TabPage tp = TaskBarRef.tabControl1.TabPages[strTabToRemove]; 
    tp.Controls.Remove(this); 
    TaskBarRef.tabControl1.TabPages.Remove(tp); 
} 

Sto cercando di chiudere una scheda nel TabControl di applicazione delle finestre utilizzando il codice di cui sopra e ho incontrato l'errore:

Cross-thread operation not valid.

Come risolvi questo ?

+2

anche una ricerca su "cross thread" in SO dà un sacco di risultati ... – Stormenet

risposta

25

È possibile modificare solo i controlli WinForm dal thread principale. È necessario verificare se InvokeRequired è true sul controllo e quindi Richiama il metodo in base alle esigenze.

Si può fare qualcosa di simile per farlo funzionare:

public void CheckUnusedTabs(string strTabToRemove) 
{ 
    if (TaskBarRef.tabControl1.InvokeRequired) 
    { 
     TaskBarRef.tabControl1.Invoke(new Action<string>(CheckUnusedTabs), strTabToRemove); 
     return; 
    }  

    TabPage tp = TaskBarRef.tabControl1.TabPages[strTabToRemove]; 
    tp.Controls.Remove(this); 
    TaskBarRef.tabControl1.TabPages.Remove(tp); 
} 
+0

FYI, il tuo chiaro aggiornamento del codice originale è stato l'unico modo in cui sono riuscito a capire come implementare correttamente questo nel mio. Grazie. – Jason

+0

Ha funzionato, fantastico! –

5

Quando si utilizzano i thread ei controlli dell'interfaccia utente, in Winforms, è necessario utilizzare InvokeRequired per apportare modifiche ai controlli.

MODIFICA.

aggiunto un esempio.

Modulo, con pulsante e etichetta.

provare

private void button2_Click(object sender, EventArgs e) 
     { 
      Thread thread = new Thread(UpdateProcess); 
      thread.Start(); 
     } 

     private void SetLabelText(string val) 
     { 
      label1.Text = val; 
     } 
     delegate void m_SetLabel(string val); 

     private void UpdateProcess() 
     { 
      int i = 0; 

      while (true) 
      { 
       if (label1.InvokeRequired) 
       { 
        m_SetLabel setLabel = SetLabelText; 
        Invoke(setLabel, i.ToString()); 
       } 
       else 
        label1.Text = i.ToString(); 
       i++; 
       Thread.Sleep(500); 
      } 
     } 
+0

@astande puoi dirmi come? – Anuya

+0

@astander ho provato ad aggiungere ... if (TaskBarRef.tabControl1.incokerequired) – Anuya

+0

controllare la risposta, aggiunto un esempio. –

19

chiamata utilizzando invocare, perché si sta accedendo il filo GUI utilizzando un altro thread

this.Invoke((MethodInvoker)delegate() {CheckUnusedTabs(""); }); 
+0

Questo ha funzionato per me con un caso simile: l'aggiornamento della GUI da un evento esterno. –

-3

impostare la seguente variabile:

CheckIllegalCrossThreadValidation = false 
+7

CheckIllegalCrossThreadValidation è un controllo di sicurezza per impedire che alcune versioni di Windows si blocchino quando si tenta di eseguire aggiornamenti dell'interfaccia utente cross-thread. È una follia spegnerlo. –

Problemi correlati