Async – Limited_Repet_Command


Klasa LimitedRepetCommand, czyli Async command z limitem wykonań

Przeprowadziłem procedurę przeglądania swojego archiwum kodu w poszukiwaniu fragmentów, które mogę opisać na blogu. I tak oto prezentuję pierwszy fragment – klasa LimitedRepetCommand odpowiedzialna za ograniczenie częstotliwości wykonywania jakiejś akcji. Co nam daje ten kod?

  • pierwsze żądanie jest wykonywane natychmiast w kontekście wątku właściciela klasy,
  • jeśli w czasie Δ  od pierwszego wywołania zostanie zgłoszone kolejne wywołanie, czeka ono do końca okna czasowego Δ. Gdy przyjdzie jego czas, będzie wywołane w kontekście właściciela obiektów, co implikuje, że będzie w stanie manipulować GUI na takich samych prawach, jak wątek tworzący obiekt,
  • gdy podczas trwania czasu oczekiwania  Δ  pojawi się więcej niż jedno żądanie, wówczas po upływie czasu Δ  tylko raz wykonamy kontrolną funkcję,
  • jeśli po upływie czasu Δ od pierwszego wywołania pojawi się nowe żądanie, to jest wykonywane natychmiast,
  • jeśli metoda wywoływana wyrzuci wyjątek, zostanie on przechwycony i przekazany do metody obsługi.

Przykład zastosowania

  • chcemy ograniczyć częstość odświeżeń widoku aplikacji do 10 sekund,
  • w grze video gracz nie możne strzelać częściej niż co 5 sekund, jeśli jednak po oddanym strzale wyda kilka rozkazów strzału, to wykonany będzie tylko jeden po 5 sekundach.

Zwracam uwagę, że naiwna implementacja (np. taka ->) jest błędna.

Implementacja

Wywołanie zgłoszenia w czasie oczekiwania będzie zignorowane, a my chcemy, aby wykonało się na końcu czasu oczekiwania Δ. Kod spełniający warunek znajduje się poniżej. Wykorzystałem bardzo wygodną klasę SynchronizationContext pozwalającą wykonać daną funkcję w kontekście innego wątku. Zazwyczaj wykorzystuję tę metodę do manipulacji GUI z innego wątku.

Testy jednostkowe

Odnośniki

Dodaj komentarz

Twój adres email nie zostanie opublikowany.