Информация об изменениях

Сообщение Re[12]: пару вопросов от 17.03.2020 11:16

Изменено 17.03.2020 11:39 Sharov

Re[12]: пару вопросов
Здравствуйте, RushDevion, Вы писали:

S>>Упд: Кажется я понял в чем дело... Я добавил в catch Tasks.TryRemove(taskIdCopy, out _), но это все равно не помогло, т.е. whenall бросал tsckcancekexp. И тут дошло, что у нас race condition, т.е. у нас whenall может увидеть состояние задачи раньше, чем это сделает выделенный блок try\catch. Я прав?


RD>Да, я уже писал, что race condition возможен.

RD>Но главная проблема не в нем, а в том, что WhenAll ждет на неправильных тасках
RD>Получается следущее:
RD>1. Стартует parent task _
RD>2. Она запускает child task, ждет ее завершения (await task) и перехватывает TaskCancelledException
RD>3. Но в словарь добавляется child task
RD>4. Main-поток await'ит на child task, видит что она отменена, выкидывает TaskCancelledException, которое в этом потоке уже никто не перехватывает.

Похоже, выше я неправ. Нету никакого rc, т.е. он есть, но не в этом суть. Даже если я словил отмену
  try
                    {
                        await task;
                    }
                    catch (TaskCanceledException)
                    {
                        // Не спасает...
                        Console.WriteLine("TaskCanceledException2");
                        //Tasks.TryRemove(taskIdCopy, out _);
                    }


whenall все равно бросит TaskCanceledExp, т.к. все таски находятся в состоянии Canceled. Вопрос, по чему так? Я же в порождающем потоке (_ = Task.Run(...)) уже отловил отмену (я специально морозил поток с whenall и ждал обработки искл. для отмененных потоков) и await whenall все равно бросал TaskCanceledException. Почему, какой в этом смысл, разве отмененные потоки и обработанная отмена этих потоков не делают задачу completed?
Re[12]: пару вопросов
Здравствуйте, RushDevion, Вы писали:

S>>Упд: Кажется я понял в чем дело... Я добавил в catch Tasks.TryRemove(taskIdCopy, out _), но это все равно не помогло, т.е. whenall бросал tsckcancekexp. И тут дошло, что у нас race condition, т.е. у нас whenall может увидеть состояние задачи раньше, чем это сделает выделенный блок try\catch. Я прав?


RD>Да, я уже писал, что race condition возможен.

RD>Но главная проблема не в нем, а в том, что WhenAll ждет на неправильных тасках
RD>Получается следущее:
RD>1. Стартует parent task _
RD>2. Она запускает child task, ждет ее завершения (await task) и перехватывает TaskCancelledException
RD>3. Но в словарь добавляется child task
RD>4. Main-поток await'ит на child task, видит что она отменена, выкидывает TaskCancelledException, которое в этом потоке уже никто не перехватывает.

Похоже, выше я неправ. Нету никакого rc, т.е. он есть, но не в этом суть. Даже если я словил отмену
  try
                    {
                        await task;
                    }
                    catch (TaskCanceledException)
                    {
                        // Не спасает...
                        Console.WriteLine("TaskCanceledException2");
                        //Tasks.TryRemove(taskIdCopy, out _);
                    }


whenall все равно бросит TaskCanceledExp, т.к. все таски находятся в состоянии Canceled. Вопрос, по чему так? Я же в порождающем потоке (_ = Task.Run(...)) уже отловил отмену (я специально морозил поток с whenall и ждал обработки искл. для отмененных потоков) и await whenall все равно бросал TaskCanceledException. Почему, какой в этом смысл, разве отмененные потоки и обработанная отмена этих потоков не делают задачу completed?

Упд: Т.е. если мы у отмененной задачи отловили исключение TaskCanceledException, то это стату этой задачи все равно будет Canceled? И поэтому ожидание, в том числе whеnall, у такой задачи всегда бросает (ну это пример теста выше)?