2012-10-01 40 views
6

Anteriormente publiqué this pregunta relacionada con la aplicación de Async-Await en el cliente o en el servicio. Lea la pregunta antes de continuar con esta pregunta, ya que está estrechamente relacionada con la pregunta.¿Ventajas reales de Async-Await?

Basado en la respuesta que he probado el código para C# 4.0 (TPL) y C# 5.0 (Async - Await). Estoy llamando al servicio utilizando la versión asincrónica y sincronizada del método proporcionado por el servicio y comparando el número de subprocesos utilizados en cada caso. A continuación se presenta el código que estoy usando para poner a prueba los recursos utilizados:

principal, método de

List<Task<string>> tasksList = new List<Task<string>>(); 
List<int> asyncThreads = new List<int>(); 
List<int> tplThreads = new List<int>(); 
Stopwatch watch = new Stopwatch(); 
watch.Start(); 

// Call the Async version of the method 
for (int i = 0; i < 500; i++) 
{ 
    tasksList.Add(GetNameFromServiceAsync("Input" + i.ToString(), asyncThreads)); 
} 

Task.WaitAll(tasksList.ToArray()); 

watch.Stop(); 

foreach (var item in asyncThreads.Distinct()) 
{ 
    Console.WriteLine(item); 
} 

Console.WriteLine("(C# 5.0)Asynchrony Total Threads = " + asyncThreads.Distinct().Count()); 
Console.WriteLine(watch.ElapsedMilliseconds.ToString()); 

watch.Restart(); 

tasksList.Clear(); 

// Call the normal method 
for (int i = 0; i < 500; i++) 
{ 
    tasksList.Add(GetNameFromService("Input" + i.ToString(), tplThreads)); 
} 

Task.WaitAll(tasksList.ToArray()); 

watch.Stop(); 

foreach (var item in tplThreads.Distinct()) 
{ 
    Console.WriteLine(item); 
} 

Console.WriteLine("(C# 4.0)TPL Total Threads" + tplThreads.Distinct().Count()); 

Console.WriteLine(watch.ElapsedMilliseconds.ToString()); 

asíncrono y sincronización de llamadas al servicio de

static async Task<string> GetNameFromServiceAsync(string name, List<int> threads) 
{ 
    Console.WriteLine(" Start Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId); 
    var task = await client.GetNameAsync(name); 
    threads.Add(System.Threading.Thread.CurrentThread.ManagedThreadId); 
    // Console.WriteLine("End GetNameFromServiceAsync Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId); 
    return task; 
} 

static Task<string> GetNameFromService(string name, List<int> threads) 
{ 

    var task = Task<string>.Factory.StartNew(() => 
     { 
      threads.Add(System.Threading.Thread.CurrentThread.ManagedThreadId); 
     // Console.WriteLine("GetNameFromService Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId); 
      return client.GetName(name); 
     }); 

    return task; 
} 

Ahora tengo trabajó en la respuesta y descubrió los siguientes resultados:

  • Si realizo 500 llamadas al servicio, solo utiliza 4-5 hilos.
  • Las llamadas TPL producen alrededor de 44-45 hilos.
  • El tiempo para las llamadas asincrónicas es de alrededor de 17 - 18 segundos
  • El tiempo para las llamadas TPL es de alrededor de 42 - 45 segundos.

Quiero obtener algunos comentarios sobre mis hallazgos para que también puedan ser útiles para los demás miembros de la comunidad. ¿Es cuál es la respuesta de mi pregunta anterior?

EDITAR

P. Mi observación llega a la conclusión de que si utilizamos asíncrono-aguardan en lugar de Task.Factory.startNew de TPL, entonces se consumirá hilos menores. ¿CÓMO CORRECTO ES ESTO? SI NO, ENTONCES, ¿CUÁL ES LA DIRECCIÓN CORRECTA PARA HACER FRENTE A DICHA COMPARACIÓN?

P. Como estoy aprendiendo async - aguarde, quiero demostrar su valía por algún tipo de comparación y código sólido.

+8

¿Cuál es exactamente tu pregunta? –

+0

Al usar async, aguarde, podemos obtener ventajas de memoria (se usarán recursos menores). Esto es lo que obtuve de mi pregunta anterior o lo que entendí y quiero saber si esta es la respuesta. Deseo preguntar en el contexto de las ventajas de escalabilidad usando async-await. ¿Está en línea con lo que he concluido? –

+0

Una ventaja importante y explícita es que los usuarios no pueden decir que se enfrentaron a un problema asincrónico cuando hicieron un código sincrónico. –

Respuesta

12

Lado del cliente async (en comparación con el código síncrono) generalmente mejora la capacidad de respuesta en un ligero costo de memoria.

Lado del servidor async (en comparación con el código síncrono) generalmente mejora la escalabilidad al reducir el uso de memoria/subprocesos. Estas ventajas también se aplican al lado del cliente async (en comparación con el código multiproceso).

Ambas son generalizaciones extremas y ciertamente hay situaciones en las que están equivocadas.

Actualización:

Mi observación llega a la conclusión de que si utilizamos asíncrono-aguardan ..., entonces se consumirá hilos menores.

async/await permiten el código asíncrono mantenible. Por sí mismos, no tienen nada que ver con la creación de hilos.Sin embargo, a menudo se usan con Task.Run (o Task.Factory.StartNew) para crear tareas en segundo plano.

Como estoy aprendiendo async - aguarde, quiero demostrar su valía por algún tipo de comparación y código sólido.

async y await son transformaciones de compilador. Facilitan la escritura de programas asíncronos, eso es todo.

Si los compara con el código síncrono, generalmente verá una mejor capacidad de respuesta y/o escalabilidad. Si los compara con el código asíncrono existente, generalmente serán ligeramente menos eficientes, pero lo compensarán en términos de capacidad de mantenimiento del código.

+0

Gracias stephen. He actualizado mi pregunta. –

+0

Respuesta actualizada. –