Task.Run z ContinueWith oraz operatorem await

0

Mam pytanie odnośnie poniższego kodu. Dlaczego, gdy do ostatniej kontynuacji zostaje przekazane zadanie z innym statusem niż ustalony to zostaje zgłoszony wyjątek "Zadanie zostało anulowane", dlaczego po prostu ta kontynuacja nie zostanie pominięta tak jak w przypadku nie korzystania z await. Ktoś wie coś na ten temat? Byłoby to za trudne w implementacji, żeby uwzględniać wszystkie warunki, więc jeżeli Status jest inny to od razu zgłasza wyjątek i po problemie?

		private async void TaskTest()
        {
            await Task.Run(() =>
            {
                Console.WriteLine("Zadanie uruchomione");
                System.Threading.Thread.Sleep(1000);
            })
            .ContinueWith((t) =>
            {
                Console.WriteLine(t.Status);
            })
            .ContinueWith((t) =>
            {
                Console.WriteLine("Zadanie zakończone niepowodzeniem");
            }, TaskContinuationOptions.OnlyOnFaulted);

            Console.WriteLine("TaskTest zakończony");
        }

//Output
Zadanie uruchomione
RanToCompletion
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in mscorlib.dll

Jeżeli Status się zgadza czyli dla poniższego kodu wszystko jest ok, kod z kontynuacji się wykonuje, bo poprzednie zadanie ma Status Faulted

		private async void TaskTest()
        {
            await Task.Run(() =>
            {
                Console.WriteLine("Zadanie uruchomione");
                System.Threading.Thread.Sleep(3000);
            })
            .ContinueWith((t) =>
            {
                Console.WriteLine(t.Status);
                throw new Exception();
            })
            .ContinueWith((t) =>
            {
                Console.WriteLine("Zadanie zakończone niepowodzeniem");
            }, TaskContinuationOptions.OnlyOnFaulted);

            Console.WriteLine("TaskTest zakończony");
        }

//Output
Zadanie uruchomione
RanToCompletion
Exception thrown: 'System.Exception' in WindowsFormsApp.exe
Zadanie zakończone niepowodzeniem
TaskTest zakończony
1

Po co mieszać await z ContinueWith, skoro await robi ContinueWith?

0

U mnie nie rzuca wyjątkiem jeśli zmienisz void na Task, a tutaj masz wytłumaczenie dlaczego:
void vs Task

0

@Azarien: Bo nikt tego nie zabrania. Dzisiaj akurat bawiłem się w anulowanie zadań i to przerodziło się w taki oto kod, który nie działa zgodnie z oczekiwaniami.
@AdamWox wiem, o tym, nawet nie muszę zwracać Task tylko jak to opakuje w kolejnego Taska to też nie zwróci wyjątku.

0

Przerób to na coś takiego:

        private async void TaskTest()
        {
            Console.WriteLine("Zadanie uruchomione");
            await Task.Delay(3000);
            try
            {
                throw new Exception();
            }
            catch (Exception e)
            {
                Console.WriteLine("Zadanie zakończone niepowodzeniem");
            }

            Console.WriteLine("TaskTest zakończony");
        }

(nie sprawdzane, i nie do końca też robi to samo co twój kod)

Bo nikt tego nie zabrania

Ale to nie ma sensu. Po to właśnie wymyślono async/await.
Await odpala taska i resztę funkcji umieszcza pod ContinueWith.
Dzięki temu piszesz liniowy kod.

0

@Azarien mnie nie interesuje inny kod tylko taki jak napisałem. Do niczego nie jest mi to potrzebne tylko chce wiedzieć czemu akurat tak to działa. Przyszło mi jedno rozwiązania do głowy że ten await odnosi się do zadania zwracanego przez ostatnia kontynuację, a skoro tak no to rzuca wyjątek bo przecież nie może jej wykonać, ale czy na pewno to nie wiem. To jest pytanie czysto teoretyczne. Nigdy takiego kodu bym nie pisał.

1 użytkowników online, w tym zalogowanych: 0, gości: 1