Tengo una interfaz con algunas funciones asincrónicas. Algunas de las clases que implementan la interfaz no tienen nada que esperar, y algunas pueden simplemente lanzar. Es un poco molesto con todas las advertencias.
Cuando no se usa await en una función asincrónica.
¿Es posible suprimir el mensaje?
public async Task<object> test()
{
throw new NotImplementedException();
}
advertencia CS1998: este método asincrónico carece de operadores 'en espera' y se ejecutará de forma sincrónica. Considere usar el operador 'await' para esperar las llamadas API sin bloqueo, o 'await Task.Run (...)' para hacer un trabajo vinculado a la CPU en un hilo en segundo plano.
c#
asynchronous
Simón
fuente
fuente
Respuestas:
Los métodos regresan
Task
, creo.async
es un detalle de implementación, por lo que no se puede aplicar a métodos de interfaz.En estos casos, puede aprovechar el hecho de que
async
es un detalle de implementación.Si no tiene nada que hacer
await
, puede simplemente regresarTask.FromResult
:En el caso de lanzar
NotImplementedException
, el procedimiento es un poco más prolijo:Si tiene muchos métodos lanzando
NotImplementedException
(lo que en sí mismo puede indicar que una refactorización a nivel de diseño sería buena), entonces podría resumir la palabra en una clase auxiliar:La clase auxiliar también reduce la basura que el GC tendría que recolectar, ya que cada método con el mismo tipo de retorno puede compartir sus objetos
Task
yNotImplementedException
.Tengo varios otros ejemplos de tipo "constante de tarea" en mi biblioteca AsyncEx .
fuente
Task
. En cambio, su método arrojará antes de que tenga la oportunidad de crear unTask
. Realmente creo que el mejor patrón es definir unasync
método sinawait
operadores. Esto asegura que el código dentro del método sea tratado como parte delTask
.await Task.FromResult(0);
a su método. Esto no debería tener ningún impacto significativo en el rendimiento (a diferencia de Task.Yield ()).return Task.CompletedTask;
, el más simple de todos.Otra opción, si desea mantener el cuerpo de la función simple y no escribir código para admitirlo, es simplemente suprimir la advertencia con #pragma:
Si esto es lo suficientemente común, puede colocar la declaración de desactivación en la parte superior del archivo y omitir la restauración.
http://msdn.microsoft.com/en-us/library/441722ys(v=vs.110).aspx
fuente
Otra forma de preservar la palabra clave async (en caso de que quiera mantenerla) es usar:
Una vez que complete el método, simplemente puede eliminar la declaración. Lo uso mucho, especialmente cuando un método puede esperar algo, pero no todas las implementaciones lo hacen.
fuente
Task.Run
llamada.Task.CompletedTask
parece que ya no existe.Task.FromResult
es la mejor respuesta. Por lo demás, si se va a lanzar una excepción, parece otra respuesta ha entrado en juego con respecto aTask.FromException
hacer esto nunca la solución ideal. ¿Estarías de acuerdo?Hay una diferencia entre las soluciones y, estrictamente hablando, debe saber cómo la persona que llama va a llamar al método asíncrono, pero con el patrón de uso predeterminado que asume ".Wait ()" en el resultado del método - " return Task.CompletedTask " es la mejor solución.
Nota:
FromResult
no se puede comparar directamente.Código de prueba:
}
fuente
#pragma
parezca incurrir en gastos generales. Probablemente tanta sobrecarga como si en lugar de devolver hubieraCompletedTask
creado y completado unAsyncOperation
. Sería bueno poder decirle al compilador que está bien omitir eso cuando el método se ejecuta sincrónicamente de todos modos.Task.CompletedTask
es similarTask.FromResult
? Sería interesante saberlo: espero que FromResult sea el más análogo y siga siendo el de mejor rendimiento si tiene que devolver un valor.Sé que este es un hilo antiguo, y tal vez esto no tenga el efecto correcto para todos los usos, pero lo siguiente es lo más cerca que puedo llegar a poder simplemente lanzar una NotImplementedException cuando aún no he implementado un método, sin alterar la firma del método. Si es problemático, estaría feliz de saberlo, pero apenas me importa: de todos modos, solo uso esto mientras estoy en desarrollo, por lo que su rendimiento no es tan importante. Aún así, estaría feliz de saber por qué es una mala idea, si lo es.
Aquí está el tipo que agregué para hacerlo posible.
fuente
Solo como una actualización de Stephen's Answer, ya no necesita escribir la
TaskConstants
clase ya que hay un nuevo método de ayuda:fuente
En caso de que ya se vincule con Reactive Extension, también puede hacer:
Reactive y async / await son increíbles por sí mismos, pero también funcionan bien juntos.
Los incluidos necesarios son:
fuente
Podría ocurrir cs1998 a continuación.
Entonces puedes reformar a continuación.
fuente
Puede intentar esto:
fuente
Prueba esto:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Await.Warning", "CS1998:Await.Warning")]
Ver: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.suppressmessageattribute?view=netframework-4.7.2
fuente
Si no tiene nada que esperar, devuelva Task.FromResult
fuente
Aquí hay algunas alternativas dependiendo de la firma de su método.
fuente
fuente
Puede eliminar la palabra clave async del método y hacer que devuelva Task;
fuente