¿Cuál es la convención para agregar sufijos a los nombres de métodos con "Async"?
¿Debería añadirse el sufijo "Async" sólo a un método que se declara con el async
modificador?
public async Task<bool> ConnectAsync()
¿O es suficiente que el método simplemente regrese Task<T>
o Task
?
public Task<bool> ConnectAsync()
c#
.net
async-await
naming-conventions
naming
Kasperhj
fuente
fuente
Respuestas:
Creo que la verdad es ambigua incluso en la documentación de Microsoft:
http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx
Eso ya no está bien. Cualquier método con
async
es asincrónico y luego dice que debe devolver unTask
oTask<T>
, lo que no es correcto para los métodos en la parte superior de una pila de llamadas, Button_Click por ejemplo, oasync void
.Por supuesto, hay que considerar cuál es el objetivo de la convención.
Se podría decir que la
Async
convención de sufijos es comunicar al usuario de la API que el método está disponible. Para que un método sea de espera, debe regresarTask
para unTask<T>
método vacío o para un método de devolución de valor, lo que significa que solo el último puede tener el sufijoAsync
.O podría decir que la
Async
convención de sufijos es comunicar que el método puede regresar inmediatamente, abandonando el hilo actual para realizar otro trabajo y potencialmente causando carreras.Esta cita de Microsoft doc dice:
http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention
Lo cual ni siquiera menciona que sus propios métodos asincrónicos que regresan
Task
necesitan elAsync
sufijo, que creo que todos estamos de acuerdo en que lo hacen.Entonces, la respuesta a esta pregunta podría ser: ambos. En ambos casos, debe agregar
Async
métodos con laasync
palabra clave y que devuelvanTask
oTask<T>
.Le voy a pedir a Stephen Toub que aclare la situación.
Actualizar
Así que lo hice. Y esto es lo que escribió nuestro buen hombre:
La guía sucinta de la oración inicial de Stephen es bastante clara. Excluye
async void
porque es inusual querer crear una API pública con tal diseño, ya que la forma correcta de implementar un vacío asincrónico es devolver unaTask
instancia simple y dejar que el compilador haga su magia. Sin embargo, si desea unpublic async void
,Async
se recomienda agregarlo . Otrosasync void
métodos de primer nivel, como los controladores de eventos, generalmente no son públicos y no importan / califican.Para mí, me dice que si me pregunto sobre cómo agregar
Async
un sufijo a unasync void
, probablemente debería convertirlo en unasync Task
para que las personas que llaman puedan esperarlo y luego agregarloAsync
.fuente
PersonString
oPriceDecimal
así por qué usarGetAsync
: los consumidores de API de API asíncronas no deben preocuparse por esto, ya que la solicitud siempre regresa después de que todas las tareas se completan de todos modos. Es una tontería y realmente me molesta. Pero es solo otra convención que nadie sabe realmente por qué está ahí.Construyo muchos servicios de API y otras aplicaciones que llaman a otros sistemas donde la mayor parte de mi código se ejecuta de forma asincrónica.
Mi propia regla general que estoy siguiendo es:
Ejemplos:
Solo un método:
Mismo método con dos firmas:
Esto tiene sentido ya que se devuelven los mismos datos, pero lo único que difiere es la forma de devolver los datos , no los datos en sí.
También creo que estas convenciones de nomenclatura existen debido a la necesidad de introducir métodos asincrónicos y aún mantener la compatibilidad con versiones anteriores.
Sostengo que el nuevo código no debería usar el sufijo Async. Es tan obvio como el tipo de retorno de String o Int como se mencionó anteriormente en este hilo.
fuente
El patrón asincrónico basado en tareas (TAP) dicta que los métodos siempre deben devolver un
Task<T>
(oTask
) y ser nombrados con un sufijo Async ; esto es independiente del uso deasync
. AmbosTask<bool> Connect()
y se compilarán y ejecutarán bien, pero no seguirás la convención de nomenclatura TAP.async
Task<bool> Connect()
Si el cuerpo del método (independientemente del tipo de retorno o el nombre) incluye
await
, debe usarasync
; y el compilador le dirá "El operador 'await' solo se puede usar dentro de un método asincrónico. ...". VolverTask<T>
oTask
no es "suficiente" para evitar su usoasync
. Consulte async (Referencia de C #) para obtener más detalles.Ambos y siguen correctamente las convenciones de TAP. Usted podría siempre utilizar la palabra clave, pero vas a obtener una advertencia del compilador "Este método asíncrono carece '' aguardan los operadores y se ejecutará de forma sincrónica. ..." si el cuerpo no utiliza .
async
Task<bool> ConnectAsync()
Task<bool> ConnectAsync()
async
await
fuente
async
palabra clave.async
es la segunda parte de la pregunta.async
modificador. Consulte también los ejemplos de OP,public async Task<bool> ConnectAsync()
(conasync
modificador) vspublic Task<bool> ConnectAsync()
(sinasync
modificador). El nombre del método en sí tiene el sufijo "Async" en ambos casos.Task
o los métodos que tienenasync Task
.Ese. La
async
palabra clave no es el problema real aquí. Si implementa la asincronía sin usar laasync
palabra clave, el método sigue siendo "Async", en el sentido general.fuente
Dado que
Task
yTask<T>
son tipos de espera, representan una operación asincrónica. O al menos deberían representar.Debe agregar un sufijo
Async
a un método que, en algunos casos (no necesariamente todos), no devuelve un valor, sino que devuelve un contenedor alrededor de una operación en curso. Ese contenedor suele ser unTask
, pero en Windows RT puede serloIAsyncInfo
. Siga su instinto y recuerde que si un usuario de su código ve laAsync
función, sabrá que la invocación de ese método está desacoplada del resultado de ese método y que debe actuar en consecuencia.Tenga en cuenta que hay métodos como
Task.Delay
yTask.WhenAll
que regresanTask
y, sin embargo, no tienen elAsync
sufijo.También tenga en cuenta que hay
async void
métodos que representan fuego y olvidan el método asincrónico y es mejor que tenga en cuenta que el método está construido de esa manera.fuente
Yo diría que debería usar el sufijo Async si devuelve una tarea independientemente de si el método se declara con el
async
modificador o no.La razón detrás de esto es que el nombre se declara en la interfaz. La interfaz declara el tipo de retorno que es a
Task
. Luego hay dos implementaciones de esa interfaz, una implementación la implementa usando elasync
modificador, la otra no.fuente
En la programación asincrónica con async y await (C #) , Microsoft ofrece la siguiente guía:
Encuentro esta guía incompleta e insatisfactoria. ¿Significa esto que, en ausencia del
async
modificador, este método debería nombrarse enConnect
lugar deConnectAsync
?No lo creo. Como se indica en la respuesta concisa de @Servy y la respuesta más detallada de @Luke Puplett , creo que es apropiado y, de hecho, se espera que este método deba ser nombrado
ConnectAsync
(porque devuelve un awaitable). En mayor apoyo a esto, @John Skeet en esta respuesta a otra pregunta se agregaAsync
al nombre del método independientemente de la presencia delasync
modificador.Finalmente, en otra pregunta , considere este comentario de @Damien_The_Unbeliever :
De eso, infiero que es la naturaleza asincrónica del método lo que dicta cómo debe nombrarse. El usuario del método ni siquiera sabrá si el
async
modificador se usa en su implementación (sin el código fuente de C # o CIL).fuente