private async Task WaitForTaskCompletionAsync(HttpRequestScheduledTaskBase task)
        {
            if (!task.Deferral.IsInProgress)
            {
                task.Deferral.Begin();
            }

            await task.Deferral.WaitForCompletionAsync().ConfigureAwait(false);
        }
        private void AddNewTask(HttpRequestPriority priority, HttpRequestScheduledTaskBase task)
        {
            _priorityToTasksCountMap.TryGetValue(priority, out var itemsCount);

            if (itemsCount > _config.MaxHttpLoadThreads)
            {
                RemoveOldestTask(priority);
            }

            _priorityToTasksCountMap.AddOrUpdate(priority, 1, (key, value) => value + 1);
            _taskIdToTaskMap.AddOrUpdate(task.Id, task, (key, value) => task);

            lock (_queueSyncLock)
            {
                var priorityForNewItem = GetPriorityForNewItem(priority);

                _tasksQueue.Enqueue(task, priorityForNewItem);
                _perPriorityQueue[priority].Enqueue(task, priorityForNewItem);
            }
        }
        private async Task PerformTaskExecutionWorkerIterationAsync(int workerIndex, CancellationToken cancellationToken)
        {
            while (_tasksQueue.Count > 0)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                if (IsHighPriorityOnlyWorker(workerIndex))
                {
                    _tasksQueue.TryFirst(out var possibleTask);

                    if (possibleTask == null || possibleTask.Priority != _highestPriority)
                    {
                        break;
                    }
                }

                HttpRequestScheduledTaskBase task = null;

                lock (_perPriorityQueue)
                {
                    _tasksQueue.TryDequeue(out task);

                    if (task != null)
                    {
                        _perPriorityQueue[task.Priority].TryRemove(task);
                    }
                }

                if (task == null)
                {
                    break;
                }

                _taskIdToTaskMap.TryRemove(task.Id, out var _);

                _priorityToTasksCountMap.AddOrUpdate(task.Priority, 0, (key, value) => value - 1);

                await Executor.ExecuteSilentlyAsync(
                    async() =>
                {
                    if (task is CompleteHttpRequestScheduledTask scheduledTask)
                    {
                        await ExecuteAsync(scheduledTask).ConfigureAwait(false);
                    }
                    else
                    {
                        await ExecuteAsync(task as RedirectHttpRequestScheduledTask).ConfigureAwait(false);
                    }
                }).ConfigureAwait(false);

                task.Deferral.CompleteIfInProgress();
            }

            await Task.Delay(
                IsHighPriorityOnlyWorker(workerIndex)
                ?HighPriorityWorkerTaskExecutionIterationDelayInMilliseconds
                : WorkerTaskExecutionIterationDelayInMilliseconds).ConfigureAwait(false);

            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            PerformTaskExecutionWorkerIterationAsync(workerIndex, cancellationToken);
        }