Имеет ли тело ContinueWith() шанс быть вызванным до того, как ContinueWith() вернет связанную задачу?

У меня есть синхронизированный список задач, предназначенный для мониторинга.
Я хочу постепенно удалять выполненные задачи из списка. Для этого я решил использовать задачи продолжения следующим образом:

      //remove createdTask from list on termination
Task self = null!;
OnGoingHandlers.Add(self = CreatedTask.ContinueWith(tsk => OnGoingHandlers.Remove(self)));

есть ли шанс наOnGoingHandlers.Removeбыть вызванным, когдаselfвсе ещеnull?

-EDIT-
полный контекст:
у меня естьHttpListener. Прослушиватель порождает одну или несколько задач на основе содержимого JSON полученного сообщения.
Когда я останавливаю прослушиватель, я хочу знать, когда все задачи, которые он породил, выполнены.

The OnGoingHandlersэтоSynchronizedCollection<Task>.

-EDIT2-
Я избежал проблемы, изменив ее на:

      member.OnGoingHandlers.Add(CreatedTask);
CreatedTask.ContinueWith(tsk => member.OnGoingHandlers.Remove(CreatedTask), TaskScheduler.Default);

но мне все еще интересно поведение однострочной альтернативы.

1 ответ

Есть ли шанс наOnGoingHandlers.Removeбыть вызванным, когдаselfвсе ещеnull?

Да, есть. Это может произойти в случае, если процессор перегружен, и операционная система (ОС) решает приостановить текущий поток сразу послеCreatedTask.ContinueWithпозвонить и передself =назначение. Затем, пока текущий поток приостанавливается, ОС дает зеленый светThreadPoolпоток для выполнения продолжения. Шансы на это довольно малы, что делает эту гонку еще более неприятной. Это может произойти один раз в голубую луну, что приведет к ошибке, которую никто не сможет воспроизвести.

К вашему сведению, ОС может приостановить любой поток в любой момент на несколько миллисекунд (по моим измерениям до 50 мс).

Другие вопросы по тегам