Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

519
Vistas
¿Cuándo es "demasiado" asíncrono y espera? ¿Todos los métodos deben devolver Task?

Estoy construyendo un proyecto y usando métodos async y await. Todo el mundo dice que las aplicaciones asíncronas se construyen desde cero, entonces, ¿realmente debería tener algún método de sincronización? ¿Todos los métodos deben devolver una Tarea para que pueda usarla de forma asíncrona?

Tomemos un ejemplo simple, donde estoy usando Sql para cargar datos en una colección, aquí hay un código.

Este código carga datos de una tabla usando el método ExecuteQueryAsync , el método GetQuery construye el SQL, pero llamando a GetTableColumns . Una vez que se genera y ejecuta el SQL, recorro la colección y completo cada objeto llamando a GetDataFromReader .

¿Mis métodos no asíncronos deberían ser asíncronos? ¿Estoy pensando demasiado en una forma sincronizada de programación y me estoy perdiendo algo?

 public async Task<ICollection<MyObject>> ExecuteQueryAsync(Module module, List<SqlParameter> parameters) { var result = new Collection<MyObject>(); var query = GetQuery(module); using (var conn = new SqlConnection(_context.Database.Connection.ConnectionString)) { await conn.OpenAsync(); using (var cmd = new SqlCommand(query, conn)) { if (parameters != null) cmd.Parameters.AddRange(parameters.ToArray()); using (var dr = await cmd.ExecuteReaderAsync()) { while (await dr.ReadAsync()) { result.Add(GetDataFromReader(module, dr)); } } } } return result; } public string GetQuery(Module module) { return "SELECT " + string.Join(",", GetTableColumns(module).ToArray()) + " FROM [TableA] "; } public List<string> GetTableColumns(Module module) { var columnNames = new List<string>(); // get all list fields for the module var fields = (from a in module.Groups.SelectMany(a => a.Fields) select a).ToList(); foreach (var field in fields) { if (field.Type == FieldType.List) { string query = "STUFF("; query += "(SELECT ';' + [Value] FROM [TableB] FOR XML PATH(''))"; query += ", 1, 1, '') AS [" + field.ColumnName + "]"; columnNames.Add(query); } else { columnNames.Add("[" + field.ColumnName + "]"); } } return columnNames; } public MyObject GetDataFromReader(Module module, IDataReader dataReader) { var entity = new MyObject(); for (var i = 0; i < dataReader.FieldCount; i++) { object value = null; var fieldName = dataReader.GetName(i); if (!dataReader.IsDBNull(i)) { value = dataReader.GetValue(i); } entity[fieldName] = value; } return entity; }
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

La filosofía detrás de " todo asíncrono " es facilitar E/S sin bloqueo .

Es decir, su código principalmente asíncrono puede potencialmente permitir que el entorno priorice cómo se ejecuta su aplicación o servicio y lograr la mayor ejecución paralela posible en un sistema de múltiples subprocesos y procesos.

Por ejemplo, ASP.NET Web API, ASP.NET MVC o incluso ASP.NET Web Forms (code-behind) pueden aprovechar toda la asincronía para seguir atendiendo solicitudes web a otros usuarios mientras se ejecuta alguna operación asincrónica. Por lo tanto, incluso cuando un servidor web como IIS o Katana puede limitar la cantidad de solicitudes simultáneas, las operaciones asíncronas se ejecutan en un hilo separado del hilo de solicitud, y esto permite que el servidor web responda a otras solicitudes mientras que las operaciones asíncronas obtienen un resultado. y necesitan continuar:

 // While WhateverAsync is being executed, current thread can be used // by a new request and so on. // Obviously, this will work this way if WhateverAsync actually // does its work in another thread... await WhateverAsync();

Entonces... ¿necesitas implementar todo de forma asíncrona? Incluso cuando devuelve una Task , no necesita proporcionar una implementación asincrónica:

 public Task WhateverAsync() { // This creates a fake Task object which // simulates a Task that has already ended successfully // and without creating a child thread! // This, this method is a SYNCHRONOUS implementation unless // the whole method doesn't execute asynchronous operations. return Task.FromResult(true); }

Mi punto de vista aquí es...

  • ... implementar todo devolviendo una Tarea y usando el sufijo Async al final de los identificadores del método ( WhateverAsync , WhoKnowsAsync , DoStuffAsync ...)...

  • ... a menos que pueda estar seguro de que todo el método siempre ejecutará cosas muy simples que no pueden bloquear el subproceso de la aplicación/servicio durante mucho tiempo (mucho tiempo puede ser unos pocos milisegundos, ahora imagine un código que no bloquee el principal subproceso de la aplicación durante 100 ms cada vez que se llama a algún método y su código puede priorizar la ejecución de algo mientras espera 100 ms...). Incluiría aquí manipulación de cadenas, operaciones aritméticas simples, métodos de configuración...

Si su código no es asíncrono hoy, puede convertirlo en operaciones asíncronas reales sin afectar la base de código completa, ya que solo necesita cambiar Task.FromResult<T>(T result) para devolver realmente una instancia Task sin terminar.

Al final del día, sus métodos tienen una firma asíncrona y a las dependencias de ellos no les importa si son realmente asíncronos, y estas implementaciones de métodos deciden qué es asíncrono o síncrono en lugar de darle esta responsabilidad a la persona que llama. .

over 4 years ago · Santiago Trujillo Denunciar

0

Si un método no tiene operaciones async dentro, no hay ningún beneficio en hacerlo async . Solo debe tener métodos async donde tenga una operación async (E/S, base de datos, etc.).

Si su aplicación tiene muchos de estos métodos de E/S y se extienden a lo largo de su base de código, eso no es malo. Pero no solo agregue las palabras clave async en métodos síncronos.

En su caso específico, ExecuteQueryAsync se beneficia al ser asíncrono, ya que permite usar await cmd.ExecuteReaderAsync() . GetTableColumns y GetDataFromReader parecen ser métodos intensivos de CPU y no se ajustan al paradigma de espera asincrónica.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda