Используя многопоточность для цикла

Я плохо знаком с поточной обработкой и хочу сделать что-то подобное этому вопросу:

Ускорьте цикл с помощью многопоточности в C# (Вопрос)

Однако я не уверен, является ли тем решением лучшее для меня, поскольку я хочу, чтобы они продолжали бежать и никогда не закончили. (Я также использую .net 3.5, а не 2.0 что касается того вопроса.)

Я хочу сделать что-то вроде этого:

foreach (Agent agent in AgentList)
{
    // I want to start a new thread for each of these
    agent.DoProcessLoop();
}

---

public void DoProcessLoop()
{
    while (true)
    {
        // do the processing

        // this is things like check folder for new files, update database
        // if new files found
    }
}

ThreadPool был бы лучшим решением или является там чем-то, что удовлетворяет этому лучше?

Обновление: Спасибо за все большие ответы! Я думал, что объясню вариант использования более подробно. Много агентов могут загрузить файлы на папку. Каждый агент имеет их собственную папку, которая они могут загрузить активы на (файлы CSV, изображения, pdfs). Наш сервис (это предназначено, чтобы быть сервисом окон, работающим на сервере, на который они загружают свои активы, пребывают в уверенности, что я буду возвращаться с вопросами о сервисах окон когда-то скоро :)) будет продолжать проверять папку каждого агента, если какие-либо новые активы будут там, и если будет, то база данных будет обновлена и для некоторых из них статические созданные страницы HTML. Поскольку это могло требовать времени, чтобы они загрузили все, и мы хотим, чтобы они смогли видеть свои загруженные изменения в значительной степени немедленно, мы думали, что поток на агент будет хорошей идеей, поскольку никакой агент затем не должен ожидать кого-то еще для окончания (и у нас есть несколько процессоров так хотел использовать их полную мощность). Надежда это объясняет это!

Спасибо,

Annelie

8
задан Community 23 May 2017 в 12:07
поделиться

7 ответов

Учитывая конкретное использование, которое вы описываете (наблюдение за файлами), я бы посоветовал вам использовать FileSystemWatcher для определения появления новых файлов, а затем запустить поток с пулом потоков для обработки файлов до тех пор, пока больше не нужно обрабатывать - в этот момент поток завершается.

Это должно уменьшить количество операций ввода-вывода (поскольку вы не опрашиваете диск постоянно), снизить нагрузку на ЦП (поскольку при постоянном зацикливании нескольких потоков, опрашивающих диск, будут использоваться циклы), а также уменьшить количество потоков, которые вы выполняете на в любой момент (при условии, что в файловую систему не вносятся постоянные изменения).

Возможно, вы захотите открывать и читать файлы только в основном потоке и передавать данные рабочим потокам (если возможно), чтобы ограничить ввод-вывод одним потоком.

12
ответ дан 5 December 2019 в 07:57
поделиться

Одна проблема с ThreadPool заключается в том, что если пул окажется меньше, чем количество агентов, которые вы хотели бы иметь, то те, которые вы попытаетесь запустить позже может никогда не казнить. Некоторые задачи могут никогда не начать выполняться, и вы можете лишиться всего остального в своем домене приложения, которое также использует пул потоков. Вам, вероятно, лучше не идти по этому пути.

2
ответ дан 5 December 2019 в 07:57
поделиться

Хм ... как указывает Рагоци, для мониторинга файлов лучше использовать FileSystemWatcher. Однако, поскольку у вас есть дополнительные операции, вы можете думать о многопоточности.

Но будьте осторожны, независимо от того, сколько у вас процессоров, их производительность ограничена. Возможно, вы не захотите создавать столько потоков, сколько количество одновременно работающих пользователей, по той простой причине, что количество агентов может увеличиться.

0
ответ дан 5 December 2019 в 07:57
поделиться

Вы определенно не хотите используйте для этой цели ThreadPool. Потоки ThreadPool не предназначены для использования для длительно выполняемых задач («бесконечность» считается длительно выполняющейся), поскольку это, очевидно, связывает ресурсы, предназначенные для совместного использования.

Для вашего приложения, вероятно, было бы лучше создать один поток ( не из ThreadPool) и в этом потоке выполнить цикл while , внутри которого вы выполняете итерацию через Агенты собирают и обрабатывают каждого из них. В цикле while вы также должны использовать вызов Thread.Sleep , чтобы не загружать процессор максимально (есть более эффективные способы периодического выполнения кода, но Thread.Sleep будет работать для ваших целей).

Наконец, вам нужно указать способ выхода из цикла while , когда ваша программа завершается.

Обновление: Наконец, многопоточность , а не автоматически ускоряет медленно выполняющийся код. Девять женщин не могут зачать ребенка за один месяц.

2
ответ дан 5 December 2019 в 07:57
поделиться

Пока вы не обновитесь до .NET 4, ThreadPool может быть вашим лучшим вариантом. Вы также можете использовать Semaphore и AutoResetEvent для управления количеством параллельных потоков. Если вы говорите о длительной работе, то накладные расходы на запуск и управление собственными потоками невелики, а решение более элегантное. Это позволит вам использовать WorkerThread.Join (), чтобы вы могли убедиться, что все рабочие потоки завершены, прежде чем возобновить выполнение.

-1
ответ дан 5 December 2019 в 07:57
поделиться

Пул потоков полезен, когда вы ожидаете, что потоки будут появляться и прекращаться довольно регулярно, а не для заранее определенного количества потоков.

1
ответ дан 5 December 2019 в 07:57
поделиться

Я полагаю, что расширения Parallels делают это возможным:

Parallel.Foreach

http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx http://blogs.msdn.com/pfxteam/

5
ответ дан 5 December 2019 в 07:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: