OrphanReporter is blocking a thread on the ThreadPool
Description
The current OrphanReporter is using Task.Factory.StartNew with TaskCreationOptions.LongRunning to start the polling loop. This will spin up a dedicated thread for the polling loop, as was clearly desired since it's a long running process.
However, the method it is calling, DoWork, is also an async method. Once the first "await Task.Delay" is reached, the created thread is done. After the first delay is done, the remaining work will be scheduled back on the ThreadPool. It will then block that thread when it reaches _queue.TryTake (a BlockingCollection call).
Instead, this method could be constructed using a Channel<T> which allows the use of `await` to get items from the queue. Then it could safely run on the thread pool without blocking, and a plain `Task.Run` without LongRunning could be used to start the process. This is similar to the DataFlow approach used in ConfigHandler, but more modern and efficient, DataFlow is heavier than is required for this purpose.
Environment
None
Gerrit Reviews
None
Release Notes Description
None
Activity
Show:
Fixed
Pinned fields
Click on the next to a field label to start pinning.
The current OrphanReporter is using Task.Factory.StartNew with TaskCreationOptions.LongRunning to start the polling loop. This will spin up a dedicated thread for the polling loop, as was clearly desired since it's a long running process.
However, the method it is calling, DoWork, is also an async method. Once the first "await Task.Delay" is reached, the created thread is done. After the first delay is done, the remaining work will be scheduled back on the ThreadPool. It will then block that thread when it reaches _queue.TryTake (a BlockingCollection call).
Instead, this method could be constructed using a Channel<T> which allows the use of `await` to get items from the queue. Then it could safely run on the thread pool without blocking, and a plain `Task.Run` without LongRunning could be used to start the process. This is similar to the DataFlow approach used in ConfigHandler, but more modern and efficient, DataFlow is heavier than is required for this purpose.