¿Por qué? ¿Entendí mal algo?
Ejecute el siguiente código, encontrará que el resultado final nunca se muestra, lo que parece causar un punto muerto.
actualización: ejecute TestSemaphoreSlimForMixUse() unas cuantas veces más, ya que creo que ocasionalmente funciona bien.
Defina un método para llamar a SemaphoreSlim.Wait:
static void TestMethod(SemaphoreSlim sp, Action worker) { sp.Wait(); try { worker(); } finally { sp.Release(); } }Defina un método para llamar a SemaphoreSlim.WaitAsync:
static async Task TestMethodAsync(SemaphoreSlim sp, Func<Task> worker) { await sp.WaitAsync().ConfigureAwait(false); try { await worker(); } finally { sp.Release(); } }Método utilizado para la prueba: la prueba encontró que si usa uno solo, no tiene ningún problema, y si usa ambos (mezclados), sí.
public static async Task TestSemaphoreSlimForMixUse() { var taskList = new List<Task>(); var countList = new List<int>(); SemaphoreSlim sp = new SemaphoreSlim(1, 1); for (int i = 0; i < 1000; i++) { var t = Task.Run(async () => { //Note: The following two lines of code, if enabled together, cause the problem described. If only one of them is enabled, there is no problem. //await TestMethodAsync(sp, async () => { countList.Add(Environment.CurrentManagedThreadId); await Task.FromResult(0); }); //TestMethod(sp, () => { countList.Add(Environment.CurrentManagedThreadId); }); }); taskList.Add(t); } await Task.WhenAll(taskList); Console.WriteLine($"Count:{countList.Count}"); }Mi teoría es que cuando la cantidad de tareas es mayor que la cantidad máxima de subprocesos que se usan para ejecutar tareas en paralelo, puede causar un punto muerto en este caso.
Por ejemplo, si tiene 1000 tareas pero solo 4 subprocesos para ejecutar todas las tareas. Es posible que los 4 subprocesos estén esperando en TestMethod a que se libere el bloqueo, mientras que el bloqueo ya se liberó para TestMethodAsync en alguna otra tarea, pero no hay ningún subproceso disponible para continuar esa tarea porque todos están esperando el bloqueo, por lo tanto punto muerto.