Zrobiłem kilka badań i nie mogę naprawdę znaleźć preferowany sposób aktualizowania formantów formularza z wątku roboczego w języku C#. Wiem o komponencie BackgroundWorker, ale jaki jest najlepszy sposób, aby to zrobić bez użycia składnika BackgroundWorker?Jaki jest najlepszy sposób aktualizacji formantów formularza z wątku roboczego?
Odpowiedz
Istnieje ogólna reguła, która mówi, że nie aktualizuje interfejsu użytkownika z żadnego wątku innego niż sam wątek interfejsu użytkownika. Korzystanie z funkcji programu BackgroundWorker jest dobrym pomysłem, ale użytkownik nie chce, a coś dzieje się w innym wątku, należy wykonać polecenie "Invoke" lub BeginInvoke, aby zmusić delegata do wykonania metody w wątku interfejsu użytkownika.
Edycja: Jon B wykonane to dobry punkt w komentarzach:
Należy pamiętać, że Invoke() jest synchroniczne i BeginInvoke() jest asynchroniczny. Jeśli użyjesz funkcji Invoke(), musisz uważać, aby nie spowodować impasu . Polecam BeginInvoke(), chyba że naprawdę potrzebujesz wywołanie być synchroniczne.
Niektóre prosty przykład kodu:
// Updates the textbox text.
private void UpdateText(string text)
{
// Set the textbox text.
m_TextBox.Text = text;
}
public delegate void UpdateTextCallback(string text);
// Then from your thread you can call this...
m_TextBox.Invoke(new UpdateTextCallback(this.UpdateText),
new object[]{"Text generated on non-UI thread."});
Powyższy kod jest z FAQ o tym here i dłuższe bardziej zaangażować jeden here.
Dlaczego nie chcesz tego zrobić za pomocą narzędzia BackgroundWorker? Ma fantastyczne wywołanie zwrotne o nazwie ProgressChanged, które pozwala wątkowi UI wiedzieć o aktualizacjach, idealne dla aktualizacji typu paska postępu i tym podobnych.
Chciałbym również rozważyć InvokeRequired (tylko VS2008) podczas wywoływania Invoke. Są chwile, że nie będziesz aktualizować interfejsu użytkownika z osobnego wątku. Oszczędza narzut związany z tworzeniem delegata itp.
if (InvokeRequired)
{
//This.Invoke added to circumvent cross threading exceptions.
this.Invoke(new UpdateProgressBarHandler(UpdateProgressBar), new object[] { progressPercentage });
}
else
{
UpdateProgressBar(progressPercentage);
}
- 1. Jaki jest najlepszy sposób wywołania metody tuż po załadowaniu formularza?
- 2. Jaki jest najlepszy sposób aktualizacji obiektu w tablicy w ReactJS?
- 3. Jaki jest najlepszy i najłatwiejszy sposób utworzenia formularza UITableView?
- 4. Jaki jest najlepszy sposób symulacji java.lang.Thread?
- 5. Jaki jest najlepszy sposób tworzenia kreatora przy użyciu natywnych formantów WPF?
- 6. Jaki jest najlepszy sposób na integrację użytkowników ExpressionEngine z MailChimp?
- 7. Zakleszczenie podczas wywoływania wątku interfejsu użytkownika z wątku roboczego
- 8. Jaki jest preferowany sposób aktualizacji generatorów Yeoman?
- 9. Jaki jest najlepszy sposób tworzenia wdrożeń ClickOnce
- 10. Jaki jest najlepszy sposób odczytu GetResponseStream()?
- 11. Jaki jest najlepszy sposób testowania usług WCF?
- 12. Jaki jest najlepszy sposób wyszukiwania GitHub?
- 13. Jaki jest najlepszy sposób implementacji protokołów?
- 14. Jaki jest najlepszy sposób na skopiowanie listy?
- 15. Jaki jest najlepszy sposób udokumentowania kodu Perla?
- 16. Jaki jest najlepszy sposób zwiększania wyliczenia?
- 17. Jaki jest najlepszy sposób profilowania wykonywania javascript?
- 18. Jaki jest najlepszy sposób rejestrowania aktywności użytkowników?
- 19. Jaki jest najlepszy sposób na seed srand()?
- 20. Jaki jest najlepszy sposób przetestowania aplikacji szyny?
- 21. Jaki jest najlepszy sposób zamknięcia gałęzi Mercurial?
- 22. Jaki jest najlepszy sposób wykonywania jQuery .change()
- 23. Jaki jest najlepszy sposób generowania mapy witryny?
- 24. Jaki jest najlepszy sposób na wdrożenie "timera"?
- 25. android - wywoływanie wątku interfejsu użytkownika z wątku roboczego
- 26. Jaki jest najlepszy sposób tworzenia wewnętrznych produktów?
- 27. Jaki jest najlepszy sposób uczenia się WCF?
- 28. Jaki jest najlepszy sposób przełączania zmiennej binarnej?
- 29. Jaki jest najlepszy sposób przetestowania narzędzia RedirectToAction?
- 30. Jaki jest najlepszy sposób wyczyszczenia tablicy łańcuchów?
Co dokładnie robi funkcja m_TextBox.Invoke? Czy zmusza delegata do wykonania w wątku UI? – Yttrium
Dokładnie. Należy pamiętać, że funkcja Invoke() jest synchroniczna, a funkcja BeginInvoke() jest asynchroniczna. Jeśli używasz Invoke(), musisz uważać, aby nie spowodować zakleszczenia. Polecam BeginInvoke(), chyba że naprawdę potrzebujesz połączenia, aby być synchronicznym. –
Dobra rozmowa, Jon B. Powinienem to wspomnieć. Będę edytować, aby odzwierciedlić punkt. –