Имеет ли тело 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 мс).