Потоки в C # с ограниченным количеством заданий и ограниченным количеством активных потоков - PullRequest
2 голосов
/ 25 августа 2011

У меня есть цикл, который выглядит примерно так:

var list = new List<float>();
while (list.Count < wantedNumberOfJobs)
{
    var resource = ... //gets the resource
    lock (resource)
    {    
        ThreadPool.QueueUserWorkItem(DoWork, /*wrap resource and list into an object*/);
    }
}

//continue pass this point when all the threads are finished

И метод работы:

private void DoWork(object state)
{
    var list = (/*wrapperObject*/)state.List;
    var someFloat = //do the work to get the number

    lock (list)
    {
        list.Add(someFloat);
    }
}

По сути, я хочу выполнить большое, но конкретное (заданное wantedNumberOfJobs) количество выполненных работ. Каждое из этих заданий вставляет один элемент в list, как вы можете видеть в методе DoWork.

Я не уверен, что этот код убеждает меня в том, что list будет содержать wantedNumberOfJobs предметов после обозначенной точки. Я также хотел бы ограничить количество активных тем. Я использовал класс System.Threading.Semaphore, но не уверен, что это лучшее решение.

Буду признателен за любую помощь. Спасибо!

Ответы [ 5 ]

3 голосов
/ 25 августа 2011

Возможно, вы можете использовать Parallel.For, вот так:

Parallel.For(0, wantedNumberOfJobs, i => {
                var resource = ... //gets the resource   
                DoWork(Resource);
            });
2 голосов
/ 25 августа 2011

Вы действительно должны получить копию шаблонов для параллельного программирования: понимание и применение параллельных шаблонов в .NET Framework 4 .

В нем объясняется, кому использовать параллельные расширения в .net 4, и как вы можете влиять на количество одновременно выполняемых заданий. Для получения списка вам также следует заглянуть в пространство имен Concurrent , чтобы найти безопасную для потоков альтернативу.

1 голос
/ 25 августа 2011

Поскольку вы пометили этот C # 4, рассмотрите возможность использования задач из TaskPool, а не потоков из TreadPool. Это ограничит количество используемых вами потоков в зависимости от количества процессоров, которые у вас есть. Кроме того, рассмотрите возможность удаления некоторых из блокировок, поскольку каждая из них требует переключения контекста и блокировки процесса, что эффективно ограничивает или даже устраняет преимущество использования нескольких потоков.

0 голосов
/ 25 августа 2011

PLINQ может быть достаточно для вас? http://msdn.microsoft.com/en-us/library/dd460714.aspx

0 голосов
/ 25 августа 2011

Скорее всего, в list будет гораздо больше wantedNumberOfJobs предметов.Это связано с тем, что цикл while решает, стоит ли ставить в очередь новый рабочий элемент на основе текущего содержимого списка.В зависимости от того, сколько времени займет DoWork, он может поставить в очередь сотни или тысячи элементов, прежде чем какие-либо из них будут добавлены в list.

. Один из способов обойти эту проблему - заставить цикл while отслеживать число.рабочих элементов, которые он ставит в очередь, и останавливается, когда он достигает wantedNumberOfJobs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...