2009-04-02 17 views
7

Quando provo a modificare una proprietà di interfaccia utente (in particolare abilitazione) il mio thread getta System.Threading.ThreadAbortExceptionAccesso UI in un thread

Come si accede interfaccia utente in un thread.

risposta

15

È possibile utilizzare un BackgroundWorker e quindi modificare l'interfaccia utente in questo modo:

control.Invoke((MethodInvoker)delegate { 
    control.Enabled = true; 
}); 
+0

Assolutamente il modo più semplice in cui mi sono imbattuto e ho provato una moltitudine di UI per l'aggiornamento delle soluzioni di thread. Ho ottenuto il mio voto. – GONeale

+0

Vinci per aver utilizzato la quantità minima di testo e per mostrare l'esempio/spiegazione più chiara. Complimenti –

+0

Grazie al modo più semplice, risparmia il mio tempo. – Tirth

1

Come utilizzare la classe BackgroundWorker di Win Form anziché l'implicazione manuale di sincronizzazione del mouse?

3

Suppongo che stiamo parlando di WinForms qui? È necessario disporre di un singolo thread per gestirlo: il thread che ha creato il controllo in questione. Se si desidera eseguire questa operazione da un thread diverso, che è possibile rilevare utilizzando Control.InvokeRequired, è necessario utilizzare il metodo Control.Invoke per eseguire il marshalling sul thread corretto. Google quella proprietà e il metodo (rispettivamente) per alcuni modelli comuni nel fare questo.

+0

È possibile utilizzare tranquillamente BeginInvoke() nella maggior parte dei casi, a meno che non si desideri eseguire il marshalling di tutte le eccezioni generate al thread di richiamo. – Quibblesome

+0

'InvokeRequired/BeginInvoke' è troppo wordy, IMO. –

1

Utilizzare SynchronizationContext per effettuare il marshalling delle chiamate al thread dell'interfaccia utente se si desidera modificare l'interfaccia utente mentre il thread non UI è ancora in esecuzione. Altrimenti, utilizzare BackgroundWorker.

1
void button1_Click(object sender, EventArgs e) { 
    var thread = new Thread(ParalelMethod); 
    thread.Start("hello world"); 
} 
void ParalelMethod(object arg) { 
    if (this.InvokeRequired) { 
     Action<object> dlg = ParalelMethod; 
     this.Invoke(dlg, arg); 
    } 
    else { 
     this.button1.Text = arg.ToString(); 
    } 
} 
6

Se si sta utilizzando C# 3.5, è veramente facile da usare metodi di estensione e lambda per impedire l'aggiornamento della UI da altri thread.

public static class FormExtensions 
{ 
    public static void InvokeEx<T>(this T @this, Action<T> action) where T : Form 
    { 
    if (@this.InvokeRequired) 
    { 
     @this.Invoke(action, @this); 
    } 
    else 
    { 
     action(@this); 
    } 
    } 
} 

Così ora è possibile utilizzare InvokeEx su qualsiasi forma e in grado di accedere a qualsiasi proprietà/campi che non fanno parte della Form.

this.InvokeEx(f => f.label1.Text = "Hello"); 
Problemi correlati