Repository: dotnet/runtime
File: src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs (C#)

Code before:
            object? workItem = DequeueWithPriorityAlternation(workQueue, tl, out bool missedSteal);
            if (workItem == null)
            {
                if (s_assignableWorkItemQueueCount > 0)
                {
                    workQueue.UnassignWorkItemQueue(tl);
                }

                // Missing a steal means there may be an item that we were unable to get.
                // Effectively, we failed to fulfill our promise to check the queues after
                // clearing "Scheduled" flag.
                // We need to make sure someone will do another pass.
                if (missedSteal)
                {
                    workQueue.EnsureThreadRequested();
                }

                // Tell the VM we're returning normally, not because Hill Climbing asked us to return.
                return true;
            }

            // The workitems that are currently in the queues could have asked only for one worker.
            // We are going to process a workitem, which may take unknown time or even block.
            // In a worst case the current workitem will indirectly depend on progress of other
            // items and that would lead to a deadlock if no one else checks the queue.
            // We must ensure at least one more worker is coming if the queue is not empty.
            workQueue.EnsureThreadRequested();

            //
            // After this point, this method is no longer responsible for ensuring thread requests except for missed steals
            //

            // Has the desire for logging changed since the last time we entered?
            workQueue.RefreshLoggingEnabled();

            object? threadLocalCompletionCountObject = tl.threadLocalCompletionCountObject;
            Thread currentThread = tl.currentThread;

            // Start on clean ExecutionContext and SynchronizationContext
            currentThread._executionContext = null;
            currentThread._synchronizationContext = null;

            //
            // Save the start time
            //
            int startTickCount = Environment.TickCount;

            //
            // Loop until our quantum expires or there is no work.
            //
            while (true)

Review comment (bug):
The comment states "if the queue is not empty" but the call to `EnsureThreadRequested()` on line 949 is unconditional. The comment should be updated to reflect that a thread is always requested when a work item is dequeued, regardless of whether more items remain:

```csharp
// The workitems that are currently in the queues could have asked only for one worker.
// We are going to process a workitem, which may take unknown time or even block.
// In a worst case the current workitem will indirectly depend on progress of other
// items and that would lead to a deadlock if no one else checks the queue.
// We must ensure at least one more worker is coming to check for additional work.
```
```suggestion
            // We must ensure at least one more worker is coming to check for additional work,
            // regardless of whether more items remain in the queue.
```

Code after:
            return workItem;
        }

        /// <summary>
        /// Dispatches work items to this thread.
        /// </summary>
        /// <returns>
        /// <c>true</c> if this thread did as much work as was available or its quantum expired.
        /// <c>false</c> if this thread stopped working early.
        /// </returns>
        internal static bool Dispatch()
        {
            ThreadPoolWorkQueue workQueue = ThreadPool.s_workQueue;
            ThreadPoolWorkQueueThreadLocals tl = workQueue.GetOrCreateThreadLocals();

            if (s_assignableWorkItemQueueCount > 0)
            {
                workQueue.AssignWorkItemQueue(tl);
            }

            // Before dequeuing the first work item, acknowledge that the thread request has been satisfied
            workQueue._separated._hasOutstandingThreadRequest = 0;

            // The state change must happen before sweeping queues for items.
            Interlocked.MemoryBarrier();

            object? workItem = DequeueWithPriorityAlternation(workQueue, tl, out bool missedSteal);
            if (workItem == null)
            {
                if (s_assignableWorkItemQueueCount > 0)
                {
                    workQueue.UnassignWorkItemQueue(tl);
                }

                // Missing a steal means there may be an item that we were unable to get.
                // Effectively, we failed to fulfill our promise to check the queues after
                // clearing the outstanding thread request flag.
                // We need to make sure someone will do another pass.
                if (missedSteal)
                {
                    workQueue.EnsureThreadRequested();
                }

                // Tell the VM we're returning normally, not because Hill Climbing asked us to return.
                return true;
            }

            // The workitems that are currently in the queues could have asked only for one worker.
            // We are going to process a workitem, which may take unknown time or even block.
            // In a worst case the current workitem will indirectly depend on progress of other
            // items and that would lead to a deadlock if no one else checks the queue.