Elidir asíncrono y esperar en métodos asíncronos.

una pregunta rapida leyendo este artículo: http://blog.stephencleary.com/2016/12/eliding-async-await.html

generalmente me dice, use async / await. Ya estoy haciendo eso. Sin embargo, también está diciendo que no tiene que usar la parte asíncrona cuando está ejecutando la tarea.

// Simple passthrough to next layer: elide. Task PassthroughAsync(int x) => _service.DoSomethingPrettyAsync(x); // Simple overloads for a method: elide. async Task DoSomethingPrettyAsync(CancellationToken cancellationToken) { ... // Core implementation, using await. } 

¿Por qué no se debe usar async / await cuando se pasa? ¿No es eso menos conveniente, y esto tiene sentido?

¿Algún pensamiento de alguien?

¿Por qué no se debe usar async / await cuando se pasa?

porque en el momento en que escribe await , el comstackdor agrega una tonelada de pegamento de implementación que no hace absolutamente nada por usted ; la persona que llama ya puede esperar la tarea del proxy.

Si agrego algo como tu PassthroughAsync , pero con el async / await :

 async Task AwaitedAsync(int x) => await DoSomethingPrettyAsync(x); 

Entonces podemos ver el código enorme pero completamente redundante al comstackrlo y descomstackr el IL:

 [AsyncStateMachine(typeof(d__1))] private Task AwaitedAsync(int x) { d__1 d__ = default(d__1); d__.<>4__this = this; d__.x = x; d__.<>t__builder = AsyncTaskMethodBuilder.Create(); d__.<>1__state = -1; AsyncTaskMethodBuilder <>t__builder = d__.<>t__builder; <>t__builder.Start(ref d__); return d__.<>t__builder.Task; } [StructLayout(LayoutKind.Auto)] [CompilerGenerated] private struct d__1 : IAsyncStateMachine { public int <>1__state; public AsyncTaskMethodBuilder <>t__builder; public C <>4__this; public int x; private TaskAwaiter <>u__1; private void MoveNext() { int num = <>1__state; C c = <>4__this; string result; try { TaskAwaiter awaiter; if (num != 0) { awaiter = c.DoSomethingPrettyAsync(x).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this); return; } } else { awaiter = <>u__1; <>u__1 = default(TaskAwaiter); num = (<>1__state = -1); } result = awaiter.GetResult(); } catch (Exception exception) { <>1__state = -2; <>t__builder.SetException(exception); return; } <>1__state = -2; <>t__builder.SetResult(result); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { <>t__builder.SetStateMachine(stateMachine); } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } 

Ahora contraste con lo que comstack el passthru no async :

 private Task PassthroughAsync(int x) { return DoSomethingPrettyAsync(x); } 

Además de omitir una gran cantidad de inicialización de struct y llamadas a métodos, un posible “cuadro” en el montón si en realidad es asíncrono (no “encaja” en el caso sincronizado ya completado), este PassthroughAsync también será un gran candidato para la incorporación de JIT, por lo que en los códigos de operación reales de la CPU , PassthroughAsync probablemente ni siquiera exista.