Все это допустимые проблемы, и PLINQ / TPL не пытается их устранить. Ваша задача как разработчика - писать код, который может работать правильно при распараллеливании. Нет ничего волшебного в том, что компилятор / TPL / PLINQ может преобразовать код, небезопасный для многопоточности, в потокобезопасный код ... вы должны убедиться, что вы это делаете.
В некоторых описанных вами ситуациях вы должны сначала решить, является ли распараллеливание целесообразным. Если узким местом будет установление соединения с базой данных или обеспечение правильной последовательности операций, то, возможно, многопоточность не необходимо.
В случае, когда TPL передает поток, перечисляемый нескольким потокам, ваше предположение верно. Последовательность перечисляется в одном потоке, и каждый рабочий элемент затем (потенциально) отправляется в отдельный поток, для которого необходимо выполнить действие. Интерфейс IEnumerable<T>
по своей природе не потокобезопасен, но TPL обрабатывает это за кулисами для вас.
PLINQ / TPL помогает вам в управлении, когда и как распределять работу по нескольким потокам. TPL обнаруживает наличие нескольких ядер на машине и автоматически масштабирует количество используемых потоков. обрабатывать данные. Если машина имеет только один процессор / ядро, то TPL может выбрать , чтобы не распараллеливать работу. Вам, разработчику, не нужно писать два разных пути - один для параллельной логики, другой для последовательного. Однако вы по-прежнему несете ответственность за одновременный безопасный доступ к вашему коду из нескольких потоков.
Какому шаблону дизайна я должен следовать
решить эти проблемы?
Нет единого ответа на этот вопрос ... однако, общепринятая практика - использовать неизменность в дизайне вашего объекта. Неизменность делает более безопасным использование объекта в нескольких потоках и является одним из наиболее распространенных способов обеспечения возможности выполнения операций. Фактически, такие языки, как F #, широко используют неизменяемость, чтобы позволить языку облегчить параллельное программирование.
Если вы работаете в .NET 4.0, вам также следует изучить ConcurrentXXX
классы коллекций в System.Collections.Concurrent
. Здесь вы найдете несколько незакрытых и детализированных конструкций коллекции блокировок, которые облегчают написание многопоточного кода.