I am using a WebClient to upload a string an retreive the answer from the server. To get the job done quicker, I decided to use the ThreadPool, but I need to know when all the downloads are over.
So far, I've been using a CountdownEvent which is supposed to decrease when the server's answer has been processed.
My main thread executes this :
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");
And here is, in another class, the code that is supposed to be executed by each thread :
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);
}
The thing is that the delegate refuses to execute, as if the "cde.Wait()" is also forcing the thread handling the delegate to wait. How can I fix / avoid that?
First off, the thread pool isn't really doing anything here. You're only starting an asynchronous operation in the thread pool. Starting such an operation takes basically no time at all. You may as well just do it in the main thread.
As for why the main thread is being blocked; that's easy, you're blocking the main thread yourself by waiting on the countdown event.
There is no way to have the main thread block until the async operation completes without blocking the main thread. They're literally contradictory requirements.
Instead you need to make your entire program asynchronous, to avoid blocking the main thread. Have this method take a callback that it should execute when the async operation completes, for example. The other option is to use the Task Parallel Library. Tasks make working with asynchronous operations quite a lot easier, especially if you're in a position to leverage the
await
keyword.