Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

370
Views
¿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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!