2012-03-31 19 views
7

W mojej aplikacji WPF ładuję zawartość przy użyciu Dispatcher.BeginInvoke w konstruktorze. Moje pytanie brzmi: czy zablokuje wątek interfejsu użytkownika?Jaka jest różnica między Dispatcher.BeginInvoke a Task.Factory.StartNew

A może lepiej użyć Task.Factory.StartNew, a następnie wysłać rzeczy z powrotem do interfejsu użytkownika, aby aplikacja ładowała się najpierw niezależnie od czasu ładowania treści?

Które podejście jest lepsze i dlaczego?

Odpowiedz

20

Robią dwa bardzo różne rzeczy:

  • Task.Factory.StartNew harmonogramy delegatem do realizacji na basenie wątku gwintu. Bieżący wątek nadal działa bez oczekiwania na wynik tego zadania (asynchronizacja). Zwykle tworzysz dłużej działające zadanie w tle, aby interfejs nie był blokowany zbyt długo (nie "zamrożony").

  • Dispatcher.BeginInvoke planuje delegata do wykonania na wątku wysyłającego (UI). Zwykle robi się to, aby zaktualizować niektóre formanty UI z wynikami niektórych operacji, które zostały wykonane na wątku tła w postaci . Zasadniczo aktualizujesz tutaj interfejs użytkownika.

Aby odpowiedzieć ci na pytania bezpośrednio:

Nie należy planować długich operacji na dyspozytora wątku, zwykle chcesz tylko zaktualizować tutaj formantów UI. Kod w delegacie zostanie wykonany na wątku UI, który jest blokowany na czas wykonania. Wystarczy wpisać Thread.Sleep(10000) w swoim bieżącym kodzie (który planujesz od konstruktora), a zobaczysz, że interfejs użytkownika zamrozi. Użyj do tego zadania w tle - albo z Task lub z robotem działającym w tle (obie będą używać wątku puli wątków).

A może to lepiej użyć Task.Factory.StartNew a następnie wysyłając rzeczy z powrotem na interfejsie, dzięki czemu aplikacja załaduje pierwszy niezależnie od czas procesu ładowania treści.

Tak!

+0

Dzięki za odpowiedź, zostanie Dispatcher.BeginInvoke zablokować interfejs użytkownika ... w mojej aplikacji. muszę wywołać niektóre usługi podczas ładowania i jeśli usługa jest zatrzymana, zawiesza się interfejs użytkownika, mimo że użyłem Dispatcher.BeginInvoke, więc moim podstawowym pytaniem jest użycie dispatchera lub Task w tym przypadku? –

+2

jeśli chcesz, aby coś działało na * tle * użyj zadania, jeśli chcesz wysłać wyniki do interfejsu użytkownika, użyj 'Dispatcher.BeginInvoke' – BrokenGlass

Powiązane problemy