Kiedy próbuję zmienić właściwość UI (konkretnie enable) mój wątek rzuca System.Threading.ThreadAbortExceptionDostęp UI w wątku
Jak uzyskać dostęp UI w wątku.
Kiedy próbuję zmienić właściwość UI (konkretnie enable) mój wątek rzuca System.Threading.ThreadAbortExceptionDostęp UI w wątku
Jak uzyskać dostęp UI w wątku.
Można użyć BackgroundWorker a następnie zmienić UI tak:
control.Invoke((MethodInvoker)delegate {
control.Enabled = true;
});
Co powiesz na wykorzystanie klasy BackgroundWorker w Win Form zamiast ręcznej implementacji synchronizacji thead?
Zakładam, że mówimy tutaj o WinFormach? Musisz zarządzać tym wątkiem - wątkiem, który utworzył kontrolkę. Jeśli chcesz to zrobić z innego wątku, który możesz wykryć za pomocą metody Control.InvokeRequired, powinieneś użyć metody Control.Invoke, aby ustawić to we właściwym wątku. Google to właściwość i metoda (odpowiednio) dla niektórych wspólnych wzorców w tym.
Możesz w bezpieczny sposób używać funkcji BeginInvoke() w większości przypadków, chyba że chcesz przywrócić zgłoszony wyjątek do wątku wywołującego. – Quibblesome
'InvokeRequired/BeginInvoke' jest zbyt rozwlekły, IMO. –
Użyj SynchronizationContext
, aby zarządzać połączeniami do wątku interfejsu użytkownika, jeśli chcesz zmodyfikować interfejs, gdy wątek inny niż UI jest nadal uruchomiony. W przeciwnym razie użyj 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();
}
}
Jeśli używasz C# 3.5, że jest bardzo łatwy w użyciu metody rozszerzenie i lambdy aby zapobiec aktualizację UI z inne wątki.
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);
}
}
}
Więc teraz można używać InvokeEx
o dowolnej formie i być w stanie uzyskać dostępu do żadnych właściwości/pól, które nie są częścią Form
.
this.InvokeEx(f => f.label1.Text = "Hello");
Absolutnie najprostszy sposób, w jaki się natknąłem, i wypróbowałem wiele aktualizacji interfejsu użytkownika. Mam głos w górę. – GONeale
Wygrywasz, używając najmniejszej ilości tekstu i pokazując najbardziej przejrzysty przykład/wyjaśnienie. Kudos –
Dzięki najprostszy sposób oszczędzam mój czas. – Tirth