Загрузка строк с использованием Threadpool и ожидание завершения загрузки

Я использую WebClient для загрузки строки и получения ответа от сервера. Чтобы быстрее выполнить работу, я решил использовать ThreadPool, но мне нужно знать, когда все загрузки закончились.

До сих пор я использовал CountdownEvent, который должен уменьшаться при обработке ответа сервера.

Мой главный поток выполняет это:

CountdownEvent cde = new CountdownEvent(retour["contenu"].Count()); //Set the countdown with the number of Thread that needs to be created

foreach (var tab in retour["contenu"])
{
    App.AnniversaryViewModel.Items.Add(new Utilisateur(int.Parse((string)tab["id"])));
    System.Diagnostics.Debug.WriteLine("Création d'un utilisateur avec l'id : " + (string)tab["id"]);
    //System.Diagnostics.Debug.WriteLine("Le dernier utilisateur est : " + Items.Last<Utilisateur>().NOMPrenom);
    ThreadPool.QueueUserWorkItem(App.AnniversaryViewModel.Items.Last<Utilisateur>().telechargerLesInfos , cde); //Starts the download

}
//Waiting for every Thread to be done

cde.Wait();

System.Diagnostics.Debug.WriteLine("On a fini d'attendre");

А вот в другом классе код, который должен выполняться каждым потоком:

public void telechargerLesInfos(Object cde)
{

    APIWebTeam.sendRequest(RequestType.PROFIL, (Newtonsoft.Json.Linq.JObject reponse) =>
    {
        processInfos(reponse); //Takes the answer from the server and parse it to fill private fields
        ((CountdownEvent)cde).Signal();
    }, "&idProfil=" + id);

}

Дело в том, что делегат отказывается выполнять, как будто "cde.Wait()" также заставляет поток, обрабатывающий делегата, ждать. Как я могу исправить / избежать этого?

1 ответ

Решение

Во-первых, пул потоков здесь ничего не делает. Вы только запускаете асинхронную операцию в пуле потоков. Запуск такой операции в принципе не занимает много времени. Вы также можете просто сделать это в главном потоке.

Что касается того, почему основной поток блокируется; это легко, вы сами блокируете основной поток, ожидая события обратного отсчета.

Невозможно получить блок основного потока, пока асинхронная операция не завершится без блокировки основного потока. Это буквально противоречивые требования.

Вместо этого вам нужно сделать всю программу асинхронной, чтобы не блокировать основной поток. Пусть этот метод примет обратный вызов, который он должен выполнить, например, после завершения асинхронной операции. Другой вариант - использовать параллельную библиотеку задач. Задачи значительно облегчают работу с асинхронными операциями, особенно если вы можете использовать await ключевое слово.

Другие вопросы по тегам