Ejecutar el método asíncrono 8 veces en paralelo

¿Cómo convierto lo siguiente en un Parallel.ForEach?

public async void getThreadContents(String[] threads)
{
    HttpClient client = new HttpClient();
    List<String> usernames = new List<String>();
    int i = 0;

    foreach (String url in threads)
    {
        i++;
        progressLabel.Text = "Scanning thread " + i.ToString() + "/" + threads.Count<String>();
        HttpResponseMessage response = await client.GetAsync(url);
        String content = await response.Content.ReadAsStringAsync();
        String user;
        Predicate<String> userPredicate;
        foreach (Match match in regex.Matches(content))
        {
            user = match.Groups[1].ToString();
            userPredicate = (String x) => x == user;
            if (usernames.Find(userPredicate) != user)
            {
                usernames.Add(match.Groups[1].ToString());
            }
        }
        progressBar1.PerformStep();
    }
}

Lo codifiqué suponiendo que el procesamiento asíncrono y paralelo sería el mismo, y me di cuenta de que no lo es. Eché un vistazo a todas las preguntas que pude encontrar sobre esto, y realmente no puedo encontrar un ejemplo que lo haga por mí. La mayoría de ellos carecen de nombres de variables legibles. El uso de nombres de variables de una sola letra que no explican lo que contienen es una manera horrible de expresar un ejemplo.

Normalmente tengo entre 300 y 2000 entradas en la matriz con nombre de hilos (contiene URL a los foros) y parece que el procesamiento en paralelo (debido a las muchas solicitudes HTTP) aceleraría la ejecución.

¿Tengo que eliminar toda la asincronía (no tengo nada asíncrono fuera de foreach, solo definiciones de variables) antes de poder utilizar Parallel.ForEach? ¿Cómo debo hacer para hacer esto? ¿Puedo hacer esto sin bloquear el hilo principal?

Estoy usando .NET 4.5 por cierto.

Respuestas a la pregunta(4)

Su respuesta a la pregunta