LINQ to Objectsについて質問していると思います。したがって、コード内のSelect呼び出しはEnumerable.Select(..)に対応します。
LINQ to Objectsオペレーター自体は、実行中のスレッドを明示的にブロックしません。ただし、メモリは割り当てられます。たとえば、ToArray演算子は、結果をバッファリングするために、ますます大きな配列を割り当てます。
また、メモリの割り当てにより、スレッドがブロックされる可能性があります。メモリを割り当てるとき、CLRまたはOSは、空きメモリのチャンクを見つけるためにロックを取得する必要がある場合があります。さらに重要なことに、CLRは、メモリを割り当てるたびにガベージコレクション(GC)を実行することを決定する可能性があり、その結果、スレッドが大幅にブロックされる可能性があります。
サーバーGCがアプリケーションに適している場合は、サーバーGCをオンにして、スループットが向上するかどうかを確認できます。また、多くの場合、LINQtoObjectsクエリよりも少ないメモリ割り当てを実行する非LINQコードを記述できます。あなたの特定の例では、LINQ to Objectsは結果を小さな配列に生成し始め、結果が収まらないときはいつでも大きな配列を割り当てると思います。カスタム実装では、最初から適切なサイズの配列を割り当てて、大量の不要な割り当てを回避できる場合があります。