Parece que caí en un problema masivo y después de horas de depuración vi que el proceso sale del alcance de "usar" en RunGame1 () y la tarea nunca se completa cuando se esperaba.
async void Execute(object o) // ICommand.Execute { // fire and forget try { await RunGame2(); // RunGame1() fails to complete } finally { ... } } // This fails due to process going out of "using" scope and never completes Task RunGame1() { var info = new ProcessStartInfo("game.exe") { CreateNoWindow = true }; using var process = new Process() { StartInfo = info }; process.Start(); return process.WaitForExitAsync(); } // Have to await the Task inside the method async Task RunGame2() { var info = new ProcessStartInfo("game.exe") { CreateNoWindow = true }; using var process = new Process() { StartInfo = info }; process.Start(); await process.WaitForExitAsync(); }¿Existe un patrón para evitar esto, de modo que pueda devolver la Tarea para guardar el compilador creando una máquina de estado adicional o es algo que se debe tener en cuenta?
De hecho, este es un error común: he visto varios errores debido a similares.
En breve:
await una tarea y, a veces, puede ser ventajoso evitar la sobrecarga de la maquinaria asíncrona, especialmente en código estricto como el bucle de E/S de archivo/red, pero (y es un gran pero)try / finally (que también incluye using y lock , aunque hay otros problemas mayores con el lock en el código async ), entonces debe tener eso en cuenta , lo que generalmente significa "sí, necesita await " Sería bueno si hubiera un analizador que detectara el return de Task[<T>] / ValueTask[<T>] en un método no async , dentro de dicha región, ya que casi siempre es un error, y para las pocas veces que no lo es (donde finally no tiene nada que ver con lo que se devuelve) podría suprimirse.