Выполняйте определенные фоновые задачи в отдельном пуле потоков, чтобы избежать истощения критически важных задач, выполC#

Место общения программистов C#
Ответить
Anonymous
 Выполняйте определенные фоновые задачи в отдельном пуле потоков, чтобы избежать истощения критически важных задач, выпол

Сообщение Anonymous »

Выполнять определенные фоновые задачи (не потоки) в отдельном пуле потоков, чтобы избежать истощения критических задач (не потоков), выполняемых в основном потоке

Наш сценарий
У нас размещен крупномасштабный веб-сервис WCF, который логически имеет следующий код:

Код: Выделить всё

void WcfApiMethod()
{
// logic

// invoke other tasks which are critical
var mainTask = Task.Factory.StartNew(() => { /* important task */ });
mainTask.Wait();

// invoke background task which is not critical
var backgroundTask = Task.Factory.StartNew(() => { /* some low-priority background action (not entirely async) */ });
// no need to wait, as this task is best effort. Fire and forget

// other logic
}

// other APIs
Теперь проблема: в некоторых сценариях фоновая задача с низким приоритетом может занять больше времени (~ 30 секунд), например, для обнаружения проблемы с соединением SQL, производительности БД проблемы, проблемы с кешем Redis и т. д., что приведет к задержке этих фоновых потоков, а это означает, что ОБЩЕЕ СЧЕТЧИК ОЖИДАЮЩИХ ЗАДАЧ увеличится из-за большого объема.

Это создает сценарий, в котором новые исполнения API не могут запланировать задачу с высоким приоритетом, поскольку в очереди находится множество фоновых задач.

Решения, которые мы опробовали
  • Добавление TaskCreationOptions.LongRunning в высокопроизводительную pri задача немедленно выполнит ее.
    Однако для нас это не может быть решением, так как повсюду в системе вызывается множество задач, и мы не можем сделать их везде долговыполняющимися.
    Кроме того, обработка WCF входящих API будет зависеть от пула потоков .NET, который сейчас находится в нехватке.
  • Короткое замыкание с низкой ценой создание фоновой задачи через семафор. Создавать потоки только в том случае, если у системы есть возможность их обработать (проверьте, завершились ли ранее созданные потоки). Если нет, просто не создавайте темы.
    Например, из-за проблемы (скажем, проблемы с производительностью БД) около 10 000 фоновых потоков (не асинхронных) находятся в режиме ожидания ввода-вывода, что может привести к нехватке потоков в основном пуле потоков .net.
    В этом конкретном случае мы могли бы добавить семафор, чтобы ограничить создание до 100, поэтому, если 100 задач зависнут, 101-я задача не будет создана в первую очередь.
Спросите об альтернативном решении

Есть ли способ специально создавать «задачи» в «пользовательских потоках/пуле потоков» вместо пула потоков .NET по умолчанию.
Это для фоновых задач, о которых я упоминал, поэтому в случае их задержки они не разрушат всю систему.
Можно переопределить и создать собственный TaskScheduler для передачи в Task.Factory.StartNew(), чтобы созданные задачи НЕ находились в пуле потоков .NET по умолчанию, а в каком-то другом пользовательском пуле.

Подробнее здесь: https://stackoverflow.com/questions/608 ... ation-to-c
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»