Сообщение 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, т.е. он есть, но не в этом суть. Даже если я словил отмену
whenall все равно бросит TaskCanceledExp, т.к. все таски находятся в состоянии Canceled. Вопрос, по чему так? Я же в порождающем потоке (_ = Task.Run(...)) уже отловил отмену (я специально морозил поток с whenall и ждал обработки искл. для отмененных потоков) и await whenall все равно бросал TaskCanceledException. Почему, какой в этом смысл, разве отмененные потоки и обработанная отмена этих потоков не делают задачу completed?
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, т.е. он есть, но не в этом суть. Даже если я словил отмену
whenall все равно бросит TaskCanceledExp, т.к. все таски находятся в состоянии Canceled. Вопрос, по чему так? Я же в порождающем потоке (_ = Task.Run(...)) уже отловил отмену (я специально морозил поток с whenall и ждал обработки искл. для отмененных потоков) и await whenall все равно бросал TaskCanceledException. Почему, какой в этом смысл, разве отмененные потоки и обработанная отмена этих потоков не делают задачу completed?
Упд: Т.е. если мы у отмененной задачи отловили исключение TaskCanceledException, то это стату этой задачи все равно будет Canceled? И поэтому ожидание, в том числе whеnall, у такой задачи всегда бросает (ну это пример теста выше)?
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, у такой задачи всегда бросает (ну это пример теста выше)?