Czytanie przez answers to this question skłoniło mnie do zastanowienia się nad tym, co dzieje się w wyjątkowych sytuacjach, gdy oczekiwane zadanie rzuca. Czy wszyscy "klienci" dostrzegają wyjątek? Przyznaję, że mogę pomylić kilka rzeczy tutaj; to jest powód, dla którego proszę o wyjaśnienia.Co się dzieje, gdy wiele równoległych wątków czeka na to samo zadanie, które następnie rzuca?
Przedstawię konkretny scenariusz ... Załóżmy, że mam serwer z globalną kolekcją długo działających instancji Task
, uruchamianych przez klientów. Po uruchomieniu jednego lub więcej zadań klient może zapytać o ich postęp i pobrać wyniki, gdy tylko staną się dostępne, a także o wszelkich błędach, które mogą wystąpić.
Zadania same w sobie mogą wykonywać bardzo różne czynności związane z biznesem - zwykle nie ma dwóch takich samych. Jeśli jednak któryś z klientów spróbuje uruchomić to samo, co inne, które wcześniej rozpoczęto, serwer powinien rozpoznać to i "dołączyć" drugiego klienta do istniejącego zadania zamiast buforować nową kopię.
Teraz, za każdym razem każdy klient pyta o stan zadania jest to interesuje, to robi coś wzdłuż tych linii:
var timeout = Task.Delay(numberOfSecondsUntilClientsPatienceRunsOut);
try
{
var result = await Task.WhenAny(timeout, task);
if (result == timeout)
{
// SNIP: No result is available yet. Just report the progress so far.
}
// SNIP: Report the result.
}
catch (Exception e)
{
// SNIP: Report the error.
}
W skrócie, to daje zadanie jakiś rozsądny czas, aby zakończyć to, co robi pierwszy , a następnie wraca do zgłaszania bieżących postępów. Oznacza to, że istnieje potencjalnie znaczący czas, w którym wielu klientów może zaobserwować to samo niepowodzenie.
Moje pytanie brzmi: czy zadanie dzieje się podczas tego okna, czy wyjątek jest obserwowany (i obsługiwany) przez wszystkich klientów?
"Zwrócone zadanie zakończy się po zakończeniu któregoś z dostarczonych zadań Zwrócone zadanie zawsze kończy się na stanie" RanToCompletion "z ustawieniem" Wynik "na pierwsze zadanie do wykonania. Jest to prawdą, nawet jeśli pierwszy zadanie do ukończenia zakończyło się stanem anulowania lub błędu. " Jeśli błędy 'task' zostaną zakończone i więcej niż jeden klient będzie oczekiwał na to przez konstrukcję, wszyscy zobaczą to zadanie. Wszystkie z nich otrzymają wyjątek, jeśli spróbują sprawdzić wynik "zadania" (a nie "wyniku"). To nie jest umowa typu "kto pierwszy, ten pierwszy raz". –
Aby uprościć to dalej: jeśli oczekujesz 'Task.Run (() => throw new Exception (DateTime.Now.Ticks.ToString()))' wiele razy z rzędu (z obsługą wyjątków), dostaniesz wyjątek za każdym razem, z tym samym znacznikiem czasu (aby udowodnić, że zadanie nie jest wykonywane wielokrotnie). Jedno błędne zadanie może wytworzyć tyle wyjątków, ile chcesz. –
Interesujące pytanie, ale łatwe do trywialnego sprawdzenia się. – spender