Chodzi mi o zaimplementowanie pewnej funkcjonalności.

Mamy klasę B, która asynchronicznie pobiera nam dużo wartości z zewnętrznego serwera. Część danych od razu wysyła do odpowiednich części programu, pozostałe dodaje do ogólnego zbiornika.

Mamy klasę A, w której mamy metodę a. W metodzie a, potrzebujemy wartości, która jest pobierana przez klasę B. Wysyłamy żądanie o taką wartość do klasy B. Jeśli nie ma jej w zbiorniku, czekamy aż się pojawi. Po 5 sekundach timeoutu rzucamy wyjątek.

Metoda a działa na osobnym wątku, podczas oczekiwania na wartość, cały wątek ma być zamrożony aż do momentu uzyskania tej wartości, albo timeoutu.

W skrócie metoda a może wyglądać tak:

public void a()
{
   try
   {
      int wartosc = B.ZadajWartosc();
   }
   catch(Exception ex)
   {
      // B.ZadajWartosc nie zwrocilo nam zadnej wartosci w ciagu 5 sekund
   }
}

Jeśli wartość będzie w zbiorniku w chwili, gdy o nią poprosimy - jest ok. Jeśli jej tam nie będzie i powiedzmy pojawi się ona za 3 sekundy - z tym mam problem. Bo w tej chwili chcę, by była ona nam zwrócona. Jedną z możliwości jest dodanie się do listy oczekujących danej wartości z podaniem callbacku - to jest chyba do zrobienia, ale ten callback nie zwróci nam wartości do metody a - mam rację?

Przeszukiwanie zbiornika co 100 milisekund w poszukiwaniu wartości, aż do jej znalezienia albo 50 prób - to lekko chybiony pomysł.

Posiadam metodę, która wywoływana jest z każdym pojawieniem się nowej wartości.
Zbiornik to zwykłe List<wartosc>.
Z identyfikacją wartości nie będzie problemu - jeśli znajdzie się w tym zbiorniku, będę mógł ją rozpoznać.

Proszę o pomoc :).

Edit:

Poleżałem w nocy, jak zwykle nie mogłem usnąć i patrząc za okno wpadłem na pomysł, żeby w klasie B w metodzie ZadajWartosc, jeśli na początku w zbiorniku nie będzie wartości, uśpić aktualny wątek na 5 sekund, wcześniej zapewniając dostęp do tego wątku pozostałym metodom w tej klasie. Jak tylko wartość się pojawi, przesyłamy do uśpionego wątku Interrupt, generując na funkcji usypiającej wyjątek, który tam łapiemy i zwracamy wartość. Jeśli wartości nie będzie, wątek po 5 sekundach się obudzi, żadnego wyjątku nie będzie i dalej będzie rzucenie nowego wyjątku o braku wartości.