Mam silnik kodu, który odtwarza długie pliki WAV, grając mniejsze kawałki po kolei przy użyciu metod waveOutOpen i waveOutWrite API. Aby zaktualizować mój interfejs podczas odtwarzania pliku, z funkcji wywołania zwrotnego po zakończeniu odtwarzania każdego buforu I Wywołaj osobny wątek (ponieważ chcesz wykonać jak najmniej funkcji wewnątrz funkcji wywołania zwrotnego), która wywołuje metodę w moim formularzu.Jak długi jest czas opóźnienia między Control.Invoke() a wywołaniem jego Delegata?
Formularz zawiera poziom klasy EventHandler
, który obsługuje metodę, w ramach której aktualizuję elementy interfejsu użytkownika o nowe informacje. W metodzie formie zwanej z funkcji zwrotnej waveOutWrite używam metody Invoke tak:
if (_updatedisplay == null)
{
// UpdateDisplay contains code to set control properties on the form
_updatedisplay = new EventHandler(UpdateDisplay);
}
Invoke(_updatedisplay);
Everythings działa, ale wydaje się, że raz na jakiś czas jest zauważalne opóźnienie lub opóźnienie w aktualizacji UI elementy. Łatwo to zauważyć, ponieważ używam metody UpdateDisplay do kierowania animacją, więc opóźnienia pojawiają się jako "czkawka", gdzie sprite wydaje się zamarzać na ułamek sekundy, zanim przeskoczy do oczekiwanej pozycji.
Czy jest możliwe, że czasami występuje długa (może 10-15 milisekundowa) zwłoka w komunikacji krzyżowej w ten sposób? Jeśli tak, jaki jest lepszy sposób obsługi czegoś takiego?
Aktualizacja: przy okazji, jestem zdecydowanie nie pewność, że Invoke
jest winowajcą tutaj. Inną możliwością jest opóźnienie pomiędzy momentem zakończenia odtwarzania dźwięku a wywołaniem funkcji wywołania zwrotnego.
Aktualizacja 2: na itowlson
jest sugestii, że stosuje się System.Diagnostics.Stopwatch
do odniesienia opóźnienie pomiędzy Invoke
i sposobu połączenia. Z 1156 pomiarów uzyskałem 1146 przy 0 ms, 8 przy 1 ms i 2 przy 2 ms. Myślę, że można bezpiecznie powiedzieć, że nie jest to mój winowajca.
Po prostu próbowałem używać BeginInvoke, ale nadal jest czkawka. Ponadto pojawia się ten sam problem, gdy próbuję uruchomić animację z oddzwanianiem z timera hi-res i mam ten sam rodzaj usterki. Zastanawiam się, czy to jest coś podstawowego z .NET UIs? – MusiGenesis
Nie, to jest fundamentalne dla * jakiegokolwiek * UI przynajmniej w zakresie działania systemu Windows. Architektura wiadomości w Windows Forms nie jest niczym nowym, tak samo działa nawet aplikacja C++ w systemie Windows.Jeśli próbujesz zaktualizować pasek postępu lub coś, czego nie powinieneś wywoływać w wątkach. Zamiast tego należy używać zapisów z blokadą do zmiennej postępu, którą wątek interfejsu użytkownika odczytuje w określonych odstępach czasu. – Josh
To * brzmi * jak * być może * komponent animacji nie jest dobrym obywatelem pod względem pompowania wiadomości, ale nie zamierzam spekulować na temat tego, co się tutaj dzieje, zwłaszcza, że nie masz pewności, czy to Wyzwanie. Spróbuj uchwycić czas, w którym BeginInvoke został wywołany i kiedy uruchomiono UpdateDisplay: to może pomóc w ustaleniu, czy wywołanie w wątku krzyżowym jest rzeczywiście problemem. (Będziesz musiał używać taktów high-res.) – itowlson