Saltar al contenido

Cómo llamar de forma segura a un método asíncrono en C# sin esperar

El tutorial o código que hallarás en este post es la solución más rápida y efectiva que hallamos a tus dudas o problema.

Solución:

Si desea obtener la excepción “asincrónicamente”, puede hacer:

  MyAsyncMethod().
    ContinueWith(t => Console.WriteLine(t.Exception),
        TaskContinuationOptions.OnlyOnFaulted);

Esto le permitirá tratar con una excepción en un hilo que no sea el hilo “principal”. Esto significa que no tiene que “esperar” la llamada para MyAsyncMethod() del hilo que llama MyAsyncMethod; pero aún le permite hacer algo con una excepción, pero solo si ocurre una excepción.

Actualizar:

técnicamente, podrías hacer algo similar con await:

try

    await MyAsyncMethod().ConfigureAwait(false);

catch (Exception ex)

    Trace.WriteLine(ex);

…que sería útil si necesitaras usar específicamente try/catch (o using) pero encuentro el ContinueWith para ser un poco más explícito porque hay que saber qué ConfigureAwait(false) significa.

Primero debe considerar hacer GetStringData un async método y tenerlo await la tarea devuelta de MyAsyncMethod.

Si está absolutamente seguro de que no necesita manejar excepciones de MyAsyncMethodo sabe cuándo se completa, entonces puede hacer esto:

public string GetStringData()

  var _ = MyAsyncMethod();
  return "hello world";

Por cierto, este no es un “problema común”. Es muy raro querer ejecutar algún código y no importar si se completa y no importa si se completa con éxito.

Actualizar:

Dado que está en ASP.NET y desea volver antes, puede encontrar útil mi publicación de blog sobre el tema. Sin embargo, ASP.NET no fue diseñado para esto y no hay garantizar que su código se ejecutará después de que se devuelva la respuesta. ASP.NET hará todo lo posible para que se ejecute, pero no puede garantizarlo.

Entonces, esta es una buena solución para algo simple como lanzar un evento en un registro donde no De Verdad importa si pierdes algunos aquí y allá. No es una buena solución para ningún tipo de operaciones críticas para el negocio. En esas situaciones, Ud. deber adopte una arquitectura más compleja, con una forma persistente de guardar las operaciones (p. ej., Azure Queues, MSMQ) y un proceso en segundo plano independiente (p. ej., Azure Worker Role, Win32 Service) para procesarlas.

La respuesta de Peter Ritchie fue lo que quería, y el artículo de Stephen Cleary sobre cómo regresar temprano a ASP.NET fue muy útil.

Sin embargo, como un problema más general (no específico de un contexto ASP.NET), la siguiente aplicación de Consola demuestra el uso y el comportamiento de la respuesta de Peter usando Task.ContinueWith(...)

static void Main(string[] args)

  try
  
    // output "hello world" as method returns early
    Console.WriteLine(GetStringData());
  
  catch
  
    // Exception is NOT caught here
  
  Console.ReadLine();


public static string GetStringData()

  MyAsyncMethod().ContinueWith(OnMyAsyncMethodFailed, TaskContinuationOptions.OnlyOnFaulted);
  return "hello world";


public static async Task MyAsyncMethod()

  await Task.Run(() =>  throw new Exception("thrown on background thread"); );


public static void OnMyAsyncMethodFailed(Task task)

  Exception ex = task.Exception;
  // Deal with exceptions here however you want

GetStringData() regresa temprano sin esperar MyAsyncMethod() y excepciones lanzadas MyAsyncMethod() se tratan en OnMyAsyncMethodFailed(Task task) y no en el try/catch alrededor GetStringData()

Calificaciones y comentarios

Si para ti ha resultado útil nuestro post, sería de mucha ayuda si lo compartes con más seniors de este modo nos ayudas a difundir esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *