Я предполагаю, что вы спрашиваете о LINQ to Objects, и поэтому вызов Select в вашем коде соответствует Enumerable.Select (..).
Операторы LINQ to Objects сами не блокируют явно выполняющийся поток. Однако они выделяют память: например, оператор ToArray будет выделять все большие и большие массивы для буферизации результатов.
И, выделение памяти может привести к блокировке потока. Когда вы выделяете память, CLR или ОС может потребоваться установить блокировку, чтобы найти кусок свободной памяти. Еще важнее то, что CLR может решить запускать сборку мусора (GC) в любое время, когда вы выделяете память, и это может привести к значительной блокировке потока.
Если серверный ГХ хорошо подходит для вашего приложения, попробуйте включить его и посмотреть, улучшится ли пропускная способность. Кроме того, вы часто можете писать не LINQ-код, который выполняет меньше выделений памяти, чем запрос LINQ to Objects. В вашем конкретном примере я полагаю, что LINQ to Objects начнет выводить результаты в небольшой массив, выделяя больший массив всякий раз, когда результаты не подходят. Ваша пользовательская реализация может быть в состоянии выделить массив правильного размера в самом начале, избегая кучу ненужных выделений.