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.
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.
È possibile utilizzare un BackgroundWorker e quindi modificare l'interfaccia utente in questo modo:
control.Invoke((MethodInvoker)delegate {
control.Enabled = true;
});
Come utilizzare la classe BackgroundWorker di Win Form anziché l'implicazione manuale di sincronizzazione del mouse?
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.
È 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
'InvokeRequired/BeginInvoke' è troppo wordy, IMO. –
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
.
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();
}
}
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");
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
Vinci per aver utilizzato la quantità minima di testo e per mostrare l'esempio/spiegazione più chiara. Complimenti –
Grazie al modo più semplice, risparmia il mio tempo. – Tirth