2009-04-02 10 views
7

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.

Odpowiedz

15

Można użyć BackgroundWorker a następnie zmienić UI tak:

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

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

+0

Wygrywasz, używając najmniejszej ilości tekstu i pokazując najbardziej przejrzysty przykład/wyjaśnienie. Kudos –

+0

Dzięki najprostszy sposób oszczędzam mój czas. – Tirth

1

Co powiesz na wykorzystanie klasy BackgroundWorker w Win Form zamiast ręcznej implementacji synchronizacji thead?

3

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.

+0

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

+0

'InvokeRequired/BeginInvoke' jest zbyt rozwlekły, IMO. –

1

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.

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

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"); 
Powiązane problemy