ThreadPool требует глобальной установки SetMaxThreads. А есть что-то, где можно инстанционально задать максимум одновременных потоков? Столько этих NuGet-пакетов уже наделали, наверняка что-то есть.
В общем, задача такая:
1. Ставите в очередь задания (1000 штук, к примеру, ждут в очереди и вы добавляете 1001).
2. Из очереди как-то достаются задания с лимитом в 7 штук (задаете), т.к. 1000 штук одновременно — не гуд. Остальные так и ждут в очереди.
3. Когда 1 из 7 завершило работу — запускается новое.
Ну и, желательно, возможность остановить обработку и пр. плюшки.
Что есть?
Ну и чтоб 2 раза не вставать. Еще нужно чтобы добавлялось в очередь с некой периодичностью (к примеру, проверка нужна раз в 5 минут, т.к. чаще — смысла нет). Если успех — удаляем из очереди. Иначе — ждет повторного вызова. Опять же — только n потоков, остальные ждут, даже если время проверки подошло.
Здравствуйте, Shmj, Вы писали:
S>Ну и чтоб 2 раза не вставать. Еще нужно чтобы добавлялось в очередь с некой периодичностью (к примеру, проверка нужна раз в 5 минут, т.к. чаще — смысла нет). Если успех — удаляем из очереди. Иначе — ждет повторного вызова. Опять же — только n потоков, остальные ждут, даже если время проверки подошло.
Подойдёт
SmartThreadPool ?
из публикации
https://www.codeproject.com/Articles/7933/Smart-Thread-Pool
Здравствуйте, Shmj, Вы писали:
S>Что есть?
на F#
///агент, ограничивающий кол-во одновременно выполняемых задач
type ThrottlingAgent(limit) =
let running = ref 0
let agent = MailboxProcessor.Start(fun inbox -> async {
// The agent body is not executing in parallel,
// so we can safely use mutable queue & counter
let queue = Queue<_>()
while true do
// Enqueue new work items or decrement the counter
// of how many tasks are running in the background
let! msg = inbox.Receive()
match msg with
| Completed -> decr running
| Work w -> queue.Enqueue(w)
// If we have less than limit & there is some work to
// do, then start the work in the background!
while running.Value < limit && queue.Count > 0 do
let work = queue.Dequeue()
incr running
async {
try
work.Invoke()
with
|_ -> ()
inbox.Post(Completed)
} |> Async.Start
})
member x.AddWork(work) = agent.Post(Work work)
member x.CurrentRunning = running.Value
interface System.IDisposable with
member __.Dispose() = (agent :> IDisposable).Dispose()
Здравствуйте, Shmj, Вы писали:
S>1. Ставите в очередь задания (1000 штук, к примеру, ждут в очереди и вы добавляете 1001).
S>2. Из очереди как-то достаются задания с лимитом в 7 штук (задаете), т.к. 1000 штук одновременно — не гуд. Остальные так и ждут в очереди.
S>3. Когда 1 из 7 завершило работу — запускается новое.
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.paralleloptions.maxdegreeofparallelism?view=netcore-3.1
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskscheduler.maximumconcurrencylevel?view=netcore-3.1... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Здравствуйте, Shmj, Вы писали:
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskscheduler?view=netcore-3.1
В статье есть реализация LimitedConcurrencyLevelTaskScheduler и пример использования. Тыришь его. И кастомизируешь, если надо. Он достаточно прост. Но чаще не надо.
Для повторного запуска задачи используешь ContinueWith или try catch в самой таске.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Здравствуйте, Shmj, Вы писали:
S>>1. Ставите в очередь задания (1000 штук, к примеру, ждут в очереди и вы добавляете 1001).
S>>2. Из очереди как-то достаются задания с лимитом в 7 штук (задаете), т.к. 1000 штук одновременно — не гуд. Остальные так и ждут в очереди.
S>>3. Когда 1 из 7 завершило работу — запускается новое.
НС>https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.paralleloptions.maxdegreeofparallelism?view=netcore-3.1
НС>https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskscheduler.maximumconcurrencylevel?view=netcore-3.1
Parallel.ForEach был создан ТОЛЬКО для синзронных операций