МенеджерФоновыхЗаданий хранит задания по Task.Id рабочей задачи, а ПолучитьТекущее() ищет задание по Task.CurrentId. Task.Id — общий счетчик процесса: он выдается при первом чтении Id, после int.MaxValue уходит в отрицательные и через 2^32 выдач повторяется.
Если к этому моменту в реестре еще выполняется задание со старым id (например, вечный главный цикл сервера):
- новое задание не попадает в реестр (
TryAdd вернет false): его не вернет ПолучитьФоновыеЗадания() и не дождется ОжидатьЗавершенияЗадач();
ПолучитьТекущее() в новом задании вернет старое задание.
При 1000 заданий в секунду это примерно 50 дней работы процесса.
Предложение: завести для реестра свой счетчик long, а текущее задание хранить в [ThreadStatic]-поле, которое менеджер выставляет на время выполнения, с восстановлением прежнего значения (Task.Wait может выполнить задачу прямо на ждущем потоке). Делать лучше после #1745, он меняет те же места.
МенеджерФоновыхЗаданийхранит задания поTask.Idрабочей задачи, аПолучитьТекущее()ищет задание поTask.CurrentId.Task.Id— общий счетчик процесса: он выдается при первом чтенииId, послеint.MaxValueуходит в отрицательные и через 2^32 выдач повторяется.Если к этому моменту в реестре еще выполняется задание со старым id (например, вечный главный цикл сервера):
TryAddвернетfalse): его не вернетПолучитьФоновыеЗадания()и не дождетсяОжидатьЗавершенияЗадач();ПолучитьТекущее()в новом задании вернет старое задание.При 1000 заданий в секунду это примерно 50 дней работы процесса.
Предложение: завести для реестра свой счетчик
long, а текущее задание хранить в[ThreadStatic]-поле, которое менеджер выставляет на время выполнения, с восстановлением прежнего значения (Task.Waitможет выполнить задачу прямо на ждущем потоке). Делать лучше после #1745, он меняет те же места.