Esperando sincrónicamente una operación asíncrona, y por qué Wait () congela el programa aquí
Prefacio: Estoy buscando una explicación, no solo una solución. Ya conozco la solución.
A pesar de haber pasado varios días estudiando artículos de MSDN sobre el Patrón asíncrono basado en tareas (TAP), asíncrono y espera, todavía estoy un poco confundido acerca de algunos de los detalles más finos.
Estoy escribiendo un registrador para las aplicaciones de la Tienda Windows, y quiero admitir el registro asíncrono y el sincronizado. Los métodos asíncronos siguen el TAP, los síncronos deberían ocultar todo esto y lucir y funcionar como métodos comunes.
Este es el método central de registro asíncrono:
private async Task WriteToLogAsync(string text)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync("log.log",
CreationCollisionOption.OpenIfExists);
await FileIO.AppendTextAsync(file, text,
Windows.Storage.Streams.UnicodeEncoding.Utf8);
}
Ahora el método síncrono correspondiente ...
Versión 1:
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Wait();
}
Esto parece correcto, pero no funciona. Todo el programa se congela para siempre.
Versión 2:
Hmm ... Tal vez la tarea no se inició?
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Start();
task.Wait();
}
Esto arrojaInvalidOperationException: Start may not be called on a promise-style task.
Versión 3:
HmmTask.RunSynchronously
suena prometedor.
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.RunSynchronously();
}
Esto arrojaInvalidOperationException: RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
Versión 4 (la solución):
private void WriteToLog(string text)
{
var task = Task.Run(async () => { await WriteToLogAsync(text); });
task.Wait();
}
Esto funciona. Entonces, 2 y 3 son las herramientas equivocadas. Pero 1? ¿Qué pasa con 1 y cuál es la diferencia con 4? ¿Qué es lo que hace que se congele? ¿Hay algún problema con el objeto de tarea? ¿Hay un punto muerto no obvio?