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?