Respostas:
Você não precisa fazer nada de especial; Parallel.Foreach()
esperará até que todas as suas tarefas ramificadas sejam concluídas. No thread de chamada, você pode tratá-lo como uma única instrução síncrona e, por exemplo, envolvê-lo em uma tentativa / captura.
Você não precisa disso com o Parallel.Foreach: ele executa o foreach apenas em quantos threads houver processadores disponíveis, mas retorna de forma síncrona.
Mais informações podem ser encontradas aqui