Besoin de comprendre l’utilisation de SemaphoreSlim

Voici le code que j’ai mais je ne comprends pas ce que fait SemaphoreSlim.

async Task WorkerMainAsync() { SemaphoreSlim ss = new SemaphoreSlim(10); List trackedTasks = new List(); while (DoMore()) { await ss.WaitAsync(); trackedTasks.Add(Task.Run(() => { DoPollingThenWorkAsync(); ss.Release(); })); } await Task.WhenAll(trackedTasks); } void DoPollingThenWorkAsync() { var msg = Poll(); if (msg != null) { Thread.Sleep(2000); // process the long running CPU-bound job } } 

Qu’est-ce qui attend ss.WaitAsync(); & ss.Release(); ss.WaitAsync(); & ss.Release(); faire?

Je suppose que si je lance 50 threads à la fois, alors écrivez du code comme SemaphoreSlim ss = new SemaphoreSlim(10); alors il sera obligé d’exécuter 10 threads actifs à la fois.

Lorsque l’un des 10 threads se termine, un autre thread commence …. si je n’ai pas raison, alors aidez-moi à comprendre avec un exemple de situation.

Pourquoi est-il nécessaire d’utiliser avec ss.WaitAsync(); ? Qu’est-ce que ss.WaitAsync(); faire?

Je suppose que si je lance 50 threads à la fois, alors code comme SemaphoreSlim ss = new SemaphoreSlim (10); va forcer à courir 10 threads actifs au moment

C’est correct l’utilisation du sémaphore garantit qu’il n’y aura pas plus de 10 travailleurs effectuant ce travail en même temps.

L’appel de WaitAsync sur le sémaphore produit une tâche qui sera terminée lorsque ce thread aura eu “access” à ce jeton. await cette tâche permet au programme de continuer l’exécution quand il est “autorisé” à le faire. Avoir une version asynchrone, plutôt que d’appeler Wait , est important à la fois pour s’assurer que la méthode rest asynchrone, plutôt que synchrone, et pour le fait qu’une méthode async peut exécuter du code sur plusieurs threads, en raison des rappels, et donc l’affinité naturelle du fil avec les sémaphores peut être un problème.

Une note de côté: DoPollingThenWorkAsync ne devrait pas avoir le postfixe Async car ce n’est pas réellement asynchrone, c’est synchrone. Appelez-le simplement DoPollingThenWork . Cela réduira la confusion pour les lecteurs.

Bien que j’accepte cette question concerne vraiment un scénario de locking du compte à rebours, j’ai pensé qu’il valait la peine de partager ce lien que j’ai découvert pour ceux qui souhaitent utiliser un SemaphoreSlim comme un simple verrou asynchrone. Il vous permet d’utiliser l’instruction using qui pourrait rendre le codage plus net et plus sûr.

http://www.tomdupont.net/2016/03/how-to-release-semaphore-with-using.html

J’ai _isDisposed=true et _semaphore.Release() autour de sa Dispose, au cas où il aurait été appelé plusieurs fois.