usar puede programación programacion paralela mvc metodos hebras ejemplos delegados con como await asíncrona async asincronos c# async-await deadlock

puede - programacion paralela c# ejemplos



Winforms llamada al método asíncrono cuelga el programa (1)

Su problema se debe a que está bloqueando el subproceso de la interfaz de usuario cuando llama .Result y le dijo a la continuación después de Task.Delay que se ejecute en el subproceso de la interfaz de usuario. Así que estás bloqueando la interfaz de usuario en espera de una tarea que está bloqueada en espera de que la interfaz de usuario se vuelva libre, un interbloqueo clásico.

Dos soluciones. Primero haz que el botón haga clic en asíncrono también.

private async void buttonOk_Click(object sender, System.EventArgs e) { var asyncResolvedIssue = api.ResolveIssue(issue, revision, pathList); if (await asyncResolvedIssue) {} // <== no deadlock! }

Los manejadores de eventos son el único lugar donde se le permite hacer un async void .

La otra opción es decirle a Task.Delay que no necesita que el resto de su función se ejecute en el subproceso de la interfaz de usuario configurando ConfigureAwait(bool) en false.

public async Task<bool> ResolveIssue(Issue issue, int revision, string[] pathList) { await Task.Delay(1000).ConfigureAwait(false); return true; }

Ahora, la línea de código después de Task.Delay se ejecutará en un subproceso de subprocesos en lugar de en el subproceso de la interfaz de usuario y no se bloqueará por el hecho de que el subproceso de la interfaz de usuario está bloqueado actualmente.

He estado trabajando alrededor de este problema por un tiempo, pero ahora realmente me gustaría entender qué está mal. Tengo una aplicación bastante simple (es un plugin SVN turtoise para youtrack, pero puedo reproducir el problema con una aplicación trivial winforms).

Tengo un método asíncrono ResolveIssue

public async Task<bool> ResolveIssue(Issue issue, int revision, string[] pathList) { await Task.Delay(1000); return true; }

Todo lo que tengo que hacer para crear un interbloqueo es llamar a este método asíncrono en un controlador de eventos Button , y llamar a Task.Wait o Task.Result , como esto

private void buttonOk_Click(object sender, System.EventArgs e) { var asyncResolvedIssue = api.ResolveIssue(issue, revision, pathList); if (asyncResolvedIssue.Result) {} // <== deadlock! }

Ahora entiendo que es bastante extraño tener un método asíncrono y esperar activamente, pero ¿por qué generaría un punto muerto?