2013-02-11 15 views
8

Środowisko:Czy program ASP.NET kontynuuje niezawodnie przetwarzanie żądania, nawet po przejściu użytkownika za pośrednictwem javascript?

  • Windows Server 2003 - IIS 6.x
  • ASP.NET 3.5 (C#)
  • IE 7,8,9
  • FF (bez względu na ostatnie 10 wersjach)

Scenariusz użytkownika:

Użytkownik wprowadza kryteria wyszukiwania przeciwko dużemu zestawowi danych. Po zainicjowaniu żądania są one kierowane na stronę wyników, gdzie czekają na załadowanie danych, a następnie mogą zawęzić dane.

Scenariusz techniczne:

Po użytkownik wysyła kryteriów (poprzez wywołanie ajax), UI nazywa obsługę back-end. Usługa typu back-end wysyła zapytania do systemów transakcyjnych i umieszcza otrzymane dane w "pamięci podręcznej" db - zdenormalizowanej tabeli, konfiguracji do dalszego udoskonalania danych (tj. Sortowania, filtrowania). Interfejs użytkownika czeka, aż dane zostaną zapisane w pamięci podręcznej, a po otrzymaniu powiadomienia o zakończeniu procesu przejdzie do wynikowej strony. Wynikowa strona wywołuje następnie wywołanie danych z tabeli zdenormalizowanej.

Problem:

Wyszukiwanie jest stosunkowo powolny (15-25 sekund) dla dużych zapytań, które kończą się konieczności kwerendy wiele systemów opartych na kryteriach zawartych. Jest stosunkowo szybki w przypadku innych zapytań (< 4 sekundy).

Ograniczenia techniczne:

  1. Nie możemy całkowicie ponownie architekt to wyszukiwanie/systemowe wyników. Istnieje tutaj wiele zawiłości między powiązaniem interfejsu i zaplecza. Strona jest wymagana (z powodu ograniczeń, których nie można rozwiązać za pomocą StackOverflow), aby włączyć po spełnieniu kryteriów wyszukiwania.

  2. Nie możemy również poprosić organizacji o denormalizację danych przed wyszukiwaniem, ponieważ dane muszą być w czasie rzeczywistym, tzn. Jeśli użytkownik wprowadza zmiany w innych systemach, dane muszą się wyświetlać poprawnie, jeśli tak się dzieje. następnie przeszukanie.

proces, który chcę podążać:

  1. chcę oszukać trochę. Chcę wydać żądanie "pamięci podręcznej" przez asynchroniczny HttpHandler w modelu zapomnieć ognia.

  2. Po wysłaniu zapytania chcę przenieść stronę na wynikową stronę.

  3. Na stronie przejściowej chcę odpytać tabelę "Pamięć podręczna", aby sprawdzić, czy dane zostały już w niej wstawione.

  4. Powodem, dla którego chcę to zrobić od razu, jest to, że strona wynikowa jest kosztowna sama w sobie (nawet bez uzyskania danych) - nadal 2 sekundy czasu ładowania, zanim nawet otrzyma połączenie z usługą, która pobiera dane z pamięci podręcznej.

Pytanie:

będzie wątek ASP.NET, która jest wywoływana przez obsługi asynchronicznego niezawodnie kontynuować przetwarzanie nawet jeśli opuścisz strony przy użyciu javascript przekierować?

Granice techniczne 2:

Tak, wiem ... Ten proces wyszukiwania nie brzmi skuteczny. Nie mogę teraz nic na to poradzić. Próbuję zrobić wszystko, co w mojej mocy, aby uzyskać nieco lepszą jakość, podczas gdy my kontynuujemy badanie tego, jak zamierzamy go ponownie zaprojektować.

Jeśli odpowiedź brzmi: "wyrzuć to i zacznij od nowa", nie odpowiadaj. To nie do przyjęcia.

+0

Ok, daj mi zobaczyć, czy to mam. Gdy użytkownicy wyślą pewne kryteria wyszukiwania, rozpoczniesz wykonywanie zapytania asynchronicznie i natychmiast przekieruje użytkownika na stronę wyników. Następnie na stronie wyników załadujesz stronę i będziesz nadal sprawdzać, czy zapytanie zostało zakończone na serwerze, aby wyświetlić wyniki dla użytkownika. Pytasz, czy wykonanie zapytania asynchronicznego będzie kontynuowane, jeśli użytkownik opuści stronę wyników? Czy to jest poprawne? –

+0

To jest prawie poprawne. Pytanie nie jest kontynuowane, jeśli użytkownik opuści stronę z wynikami, ale raczej będzie kontynuował działanie, gdy użytkownik zostanie przeniesiony na stronę wyników. Podczas testowania na moim komputerze lokalnym operacja asynchronizacji wydaje się nadal działać. Chciałbym jednak sprawdzić, jak wiarygodny jest ten proces. Czy to jest zaprojektowane zachowanie ASP.NET czy przypadek "działa na moim komputerze"? –

+0

Jeśli używasz przestrzeni nazw Threading (jesteś?) Do uruchomienia asynchronicznego przetwarzania na serwerze sieci Web, nie sądzę, aby był to przypadek "działa na moim komputerze". Powinno to zdecydowanie działać zgodnie z oczekiwaniami na IIS. –

Odpowiedz

4

Tak.

Istnieje właściwość Response.IsClientConnected, która służy do sprawdzenia, czy długo trwający proces jest nadal podłączony. Powodem tej właściwości jest to, że procesy będą nadal działać, nawet jeśli klient zostanie odłączony i musi zostać ręcznie wykryty za pośrednictwem właściwości i ręcznie zamknięty, jeśli nastąpi przedwczesne rozłączenie. Nie jest domyślnie przerywanie działającego procesu po rozłączeniu klienta.

odniesienia do tej właściwości: http://msdn.microsoft.com/en-us/library/system.web.httpresponse.isclientconnected.aspx

aktualizacja

FYI jest to bardzo złe nieruchomość polegać na tych dni z gniazd.Gorąco zachęcam do podejścia, które pozwala szybko spełnić żądanie notatek w bazie danych lub kolejce jakiegoś długiego zadania do wykonania, prawdopodobnie użyje RabbitMQ lub czegoś podobnego, które z kolei używa socket.io lub podobnego do aktualizacji strona internetowa lub aplikacja po zakończeniu.

+0

Dziękuję za link. Przyjąłem twoją odpowiedź. Pozostaje tylko pytanie, czy mogę znaleźć tę logikę. "Przyczyną tej właściwości jest to, że procesy będą nadal działać, nawet jeśli klient zostanie odłączony i musi zostać ręcznie wykryty za pośrednictwem właściwości i ręcznie zamknięty, jeśli nastąpi przedwczesne rozłączenie. "w tym źródle. Zasadniczo stwierdzasz, że gdy wątek się rozpocznie, zakończy się, chyba że wydarzy się coś wyjątkowego. –

+0

Tak. Tego też doświadczyłem w praktyce. Na przykład napisałem długotrwały proces zainicjowany przez hit strony internetowej. Statyczny członek został przełączony, aby wskazać, czy proces był uruchomiony, czy nie. Żądanie strony odpowiedziałoby, gdy "przetwarzanie nadal trwa, spróbuj ponownie później", jeśli flaga statyczna była prawdziwa.Mógłbym pójść i wrócić w tym samym oknie przeglądarki, a proces nie rozłączyłby się i zachowywał się zgodnie z oczekiwaniami, aby działał jak normalny, stanowy program podczas procesu i niezawodnie zmieniłby flagę z powrotem na fałsz, gdy byłaby zakończona (zakładając próbę-catch). –

3

Co powiesz na pytanie, czy w ogóle nie wykonujesz operacji asynchronicznej na wątku ASP.NET? Pozwól, aby kod ASP.NET wywoływał usługę do kolejkowania przeszukiwania danych, a następnie wracał do przeglądarki z tokenem z usługi, gdzie następnie przekierowałby na stronę wyników, która czeka na ukończony wynik? Strona wynikowa odpytuje za pomocą tokena z usługi.

W ten sposób nie będziesz musiał się martwić, czy program ASP.NET jakoś się dowie, że przeglądarka przeszła na inną stronę.

+0

Kolejne źródło mówiło mi o tego rodzaju rozwiązaniu. Zasadniczo, musielibyśmy mieć jakąś usługę w tle (najprawdopodobniej poza ASP.NET), która monitorowałaby dodawanie tokenów, przeprowadzała wyszukiwanie, a następnie aktualizowała token, który jest wykonywany? Brzmi świetnie, z wyjątkiem jednego małego zastrzeżenia. Nie chcemy spowalniać "szybkich" wyszukiwań (jeśli to możliwe). Ale może to być droga, którą musimy podążać, jeśli chcemy zwiększyć spójność naszych wyników bez wielkich zmian w architekturze. Nadal jestem ciekawy wewnętrznych cech zachowania ASP.NET. –

+0

Usługa nie musi "monitorować". Byłaby to usługa WCF czekająca na żądanie zawierające kryteria wyszukiwania. Zachowałby kryteria, zwrócił token reprezentujący żądanie, a następnie rozpoczął przetwarzanie wyszukiwania. Będzie śledzić postęp wyszukiwania. Zapytany później o postęp, poinformuje o postępach. Po zakończeniu zwraca wyniki wyszukiwania. –

+0

Ponadto, jeśli z wyprzedzeniem można ustalić, że "szybkie" wyszukiwanie będzie szybkie, można je wyszukać "w wierszu". Rzeczywiście, strona ASP.NET może poczekać sekundę, a następnie zapytać usługę, czy to zrobione. Jeśli nie, _then_ przekieruj do strony "oczekiwanie na wyniki". –

0

Inną opcją jest użycie gwintowania (System.Threading).
Po wysłaniu przez użytkownika kryteriów wyszukiwania serwer rozpoczyna przetwarzanie żądania strony, tworzy nowy wątek odpowiedzialny za wykonanie wyszukiwania i kończy uzyskiwanie odpowiedzi wracając do przeglądarki i przekierowując na stronę wyników, gdy wątek będzie nadal wykonywany tło serwera.
Strona wyników będzie weryfikować na serwerze, jeśli wykonanie kwerendy zostało zakończone, ponieważ rozpoczęty wątek udostępniłby informacje o postępie. Kiedy się zakończy, wyniki są zwracane, gdy następne wywołanie ajax zostanie wykonane przez stronę wyników.

Można również rozważyć użycie WebSockets. W pewnym sensie, że serwer sieci Web sam może powiedzieć przeglądarce, kiedy zakończy przetwarzanie kwerendy, ponieważ oferuje kanały komunikacji w pełnym dupleksie.

+0

Podczas gdy doceniam twoją odpowiedź, szukam autorytatywnej odpowiedzi na pytanie: "Czy wątek ASP.NET, który jest wywoływany przez moduł obsługi asynchronicznej, niezawodnie kontynuuje przetwarzanie, nawet jeśli nawiguję od strony za pomocą przekierowania javascript?" –

+0

Nowo utworzony wątek działa sam na serwerze bez połączenia ze stroną przeglądarki (bezstanowość). Nie ma między nimi żadnej relacji, która mogłaby spowodować zakończenie wątku, gdy użytkownik przekieruje na inną stronę. Ale widzę, że potrzebuję źródła. –