none
Recorrer el resultado de un TASK ASYNC en un ciclo foreach RRS feed

  • Pregunta

  • Hola a todos:

     Tengo unas funciones que trabajan con TASK ASYNC (mis primeras pruebas), en una funcion que se comunica con la BD regreso una lista de clases, esta lista llega a presentacion, en presentacion tengo la necesidad de recorrer la lista para luego pintar los registros en un control de windows forms.

     Pero no logro recorrer el result del task, estos son mis avances:

    Capa de Datos:

    public async Task<List<General>> GetData(string param)
    {
        var environment = _datos.Ambiente == Ambiente.Produccion ? "xx" : "cc";
        var resultList = new List<General>();
    
        using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings[environment].ConnectionString))
        {
            await connection.OpenAsync();
            var query = @"SELECT *
                                FROM table where param = @param";
    
            using (SqlCommand command = new SqlCommand(query, connection))
            {
                command.Parameters.AddWithValue("@param", param);
              
                using (SqlDataReader reader = await command.ExecuteReaderAsync())
                {
                    if (await reader.ReadAsync())
                    {
                        while (await reader.ReadAsync())
                        {
                            var item = new General();
                            item.ColumnName = columnName;
                            item.TableName = Convert.ToString(reader["TableName"]);
    
                            resultList.Add(item);
                        }                   
                    }
                }
            }
        }
    
        return resultList;
    }

     Capa de negocio:

    public async Task<List<General>> GetData(string param)
    {
        return await Task.Run(() => _dataAccess.GetData(param));
    }

     En presentación tengo esto:

    private Dictionary<int, string> TestData()
    {
       return Task.Run(() =>
       {
    
    
    
    
         var tablas = Task.Run(() => _businessLayer.GetData("test"));
        
    
        int counter = 0;
        foreach (var item in tablas)
        {
    		//resto de codigo
        }
    
        return //objeto;
       })
    }

     Mensaje de error:

    foreach statement cannot operate on variables of type 'Task<List<General>>' because 'Task<List<General>>' does not contain a public instance definition for 'GetEnumerator'

    cualquier ayuda es bienvenida.


    Saludos desde Monterrey, Nuevo León, México!!!

    miércoles, 12 de junio de 2019 23:59

Respuestas

  • hola

    No entiendo porque pones todo dentro de "Task.Run()", que la capa de acceso sea asincrona no quiere decir que negocio y presentacion deban aplicar lo mismo

    Podrias hacer

    public Task<List<General>> GetData(string param)
    {
        return _dataAccess.GetData(param);
    }

    sino me equivoco como retornas el Task<> y no esperas la respuesta no necesitas del async/await ya que luego sigues con

    private async Dictionary<int, string> TestData()
    {
        List<General> tablas = await _businessLayer.GetData("test"));
        
        int counter = 0;
        foreach (var item in tablas)
        {
    		//resto de codigo
        }
    	
    	//resto codigo
    
    }

    que sera donde esperas el resultado


    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    jueves, 13 de junio de 2019 2:44
  • Hola, no te hace falta ejecutar Task.Run()

    En tu capa de negocio ponlo asi

    public async Task<List<General>> GetData(string param)
    {
        return await _dataAccess.GetData(param);
    }

    Y en presentación si deseas que ese método privado sea sincrono (si lo marcas como asíncrono la respuesta de Leandro es válida) entonces aplica un solo Task.Run

    private Dictionary<int, string> TestData()
    {
    
         var tablas = Task.Run(() => _businessLayer.GetData("test"));
        
    
        int counter = 0;
        foreach (var item in tablas)
        {
    		//resto de codigo
        }
    
        return diccionario;
    }


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 13 de junio de 2019 7:13
    Moderador

Todas las respuestas

  • hola

    No entiendo porque pones todo dentro de "Task.Run()", que la capa de acceso sea asincrona no quiere decir que negocio y presentacion deban aplicar lo mismo

    Podrias hacer

    public Task<List<General>> GetData(string param)
    {
        return _dataAccess.GetData(param);
    }

    sino me equivoco como retornas el Task<> y no esperas la respuesta no necesitas del async/await ya que luego sigues con

    private async Dictionary<int, string> TestData()
    {
        List<General> tablas = await _businessLayer.GetData("test"));
        
        int counter = 0;
        foreach (var item in tablas)
        {
    		//resto de codigo
        }
    	
    	//resto codigo
    
    }

    que sera donde esperas el resultado


    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    jueves, 13 de junio de 2019 2:44
  • Hola, no te hace falta ejecutar Task.Run()

    En tu capa de negocio ponlo asi

    public async Task<List<General>> GetData(string param)
    {
        return await _dataAccess.GetData(param);
    }

    Y en presentación si deseas que ese método privado sea sincrono (si lo marcas como asíncrono la respuesta de Leandro es válida) entonces aplica un solo Task.Run

    private Dictionary<int, string> TestData()
    {
    
         var tablas = Task.Run(() => _businessLayer.GetData("test"));
        
    
        int counter = 0;
        foreach (var item in tablas)
        {
    		//resto de codigo
        }
    
        return diccionario;
    }


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 13 de junio de 2019 7:13
    Moderador
  • Hola:

     Leandro/Sergio, muchas gracias por su respuesta, el objetivo del ejercicio es ejecutar una tarea en segundo plano y reportar el avance a presentación, mi proyecto consta de 3 capas, este en realidad es mi primer ejercicio con métodos asíncronos, esa tarea consta de ejecutar 3000 consultas vs la Bd y al final retornar una lista con las consultas que devolvieron resultados, no el resultado, solo la consulta,pero en el inter necesito ir reportando el avance a presentación.

    Probare lo que comentas.


    Saludos desde Monterrey, Nuevo León, México!!!

    jueves, 13 de junio de 2019 11:55