Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

361
Vistas
¿Cómo implementar el método de devolución de tareas sincrónicas sin advertir a CS1998?

Tomemos como ejemplo la siguiente interfaz:

 interface IOracle { Task<string> GetAnswerAsync(string question); }

Algunas implementaciones de esta interfaz pueden usar async / await . Es posible que otros no necesiten hacerlo. Por ejemplo, considere esta implementación de juguete simple.

 class SimpleOracle { public Dictionary<string, string> Lookup { get; set; } // Warning CS1998: This async method lacks 'await' operators // and will run synchonously. public async Task<string> GetAnswerAsync(string question) { string answer = Lookup[question]; return answer; } }

La advertencia del compilador CS1998, por supuesto, tiene sentido. La sugerencia habitual es eliminar la palabra clave async y usar Task.FromResult , pero se pierde un problema sutil. ¿Qué sucede si el código arroja una excepción? Luego, esa transformación de código cambia el comportamiento del método: la versión async envolverá cualquier excepción en una Task ; la versión no async no lo hará, sin un try - catch explícito.

Dejar la palabra clave async funciona exactamente como quiero, pero genera una advertencia del compilador, y no creo que sea prudente suprimirla.

¿Cómo debo refactorizar la implementación de mi método para no producir una advertencia del compilador y al mismo tiempo envolver todas las excepciones con Task como lo haría cualquier otro método async ?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

La traducción mecánica que uso para convertir de la versión async que produce la advertencia del compilador CS1998 a una versión no async que se comporta de manera idéntica es la siguiente.

  • Quite la palabra clave async .
  • Envuelva todo el cuerpo del método existente con un try - catch .
  • Defina un TaskCompletionSource<T> llamado tcs antes de try - catch .
  • Reemplazar todas las instancias existentes de return <expr>; con tcs.SetResult(<expr>); seguido de return tcs.Task; .
  • Defina el bloque catch para llamar a tcs.SetException(e) seguido de return tcs.Task; .

Por ejemplo:

 public Task<string> GetAnswerAsync(string question) { var tcs = new TaskCompletionSource<string>(); try { string answer = Lookup[question]; tcs.SetResult(answer); return tcs.Task; } catch (Exception e) { tcs.SetException(e); return tcs.Task; } }

Esto se puede expresar de manera más general de la siguiente manera, aunque no sé si sería apropiado introducir un método auxiliar de este tipo en una base de código.

 public static Task<T> AsyncPattern(Func<T> func) { var tcs = new TaskCompletionSource<T>(); try { tcs.SetResult(func()); } catch (Exception e) { tcs.SetException(e); } return tcs.Task; }
over 4 years ago · Santiago Trujillo Denunciar

0

Si usa .NET 4.6, puede usar Task.FromException para manejar el caso de excepción, tal como usa FromResult para manejar el caso exitoso:

 public Task<string> GetAnswerAsync(string question) { try { return Task.FromResult(Lookup[question]); } catch(Exception e) { return Task.FromException<string>(e); } }

Si está utilizando .NET 4.5, deberá escribir su propio método FromException , pero es bastante trivial:

 public static Task<T> FromException<T>(Exception e) { var tcs = new TaskCompletionSource<T>(); tcs.SetException(e); return tcs.Task; } public static Task FromException(Exception e) { var tcs = new TaskCompletionSource<bool>(); tcs.SetException(e); return tcs.Task; }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda