Simon
Simon

Reputation: 1476

Using the async Datareader

We are pretty new to this, but we're trying to make use of the new async datareader

we have been following the sample from http://blogs.msdn.com/b/adonet/archive/2012/07/15/using-sqldatareader-s-new-async-methods-in-net-4-5-beta-part-2-examples.aspx

but experiencing problems. What we are trying to achieve is :- The stored proc returns 2 tables, using a datareader, we are trying to populate 2 models asynchronously, ie the 2 models will be created at the same time and not have to wait for the first model to be built before the second one can begin (If that makes sense?)

Below is what we have at the moment :-

   public async Task<UsertResultsModel> GetResults(string user_ID)
    {
        UsertResultsModel rm = new UsertResultsModel();
        List<TableColumn> ltc = new List<TableColumn>();
        List<List<TableColumn>> lltc = new List<List<TableColumn>>();
        var col = 0;
        try
        {
            using (SqlConnection con = new SqlConnection(Config.DatabaseStringCDA))
            {
                await con.OpenAsync();
                SqlCommand com = new SqlCommand(@"USP_GET_USER_RESULTS", con);
                com.CommandType = CommandType.StoredProcedure;


                using (SqlDataReader rdr = await com.ExecuteReaderAsync())
                {
                    col = rdr.FieldCount;
                    while (await rdr.ReadAsync())
                    {
                        for (int i = 0; i < rdr.FieldCount; i++)
                        {
                            string colName = rdr.GetName(i).ToSafeString();
                            ltc.Add(new TableColumn(colName, rdr[i].ToSafeString(), 50, EnumColumnType.String, colName));
                        }
                        lltc.Add(ltc);
                    }
                    rm.Summary = new TableViewModel { Grid = lltc };

                    await rdr.NextResultAsync();
                    lltc = new List<List<TableColumn>>();

                    while (rdr.Read())
                    {
                        for (int i = 0; i < rdr.FieldCount; i++)
                        {
                            string colName = rdr.GetName(i).ToSafeString();
                            ltc.Add(new TableColumn(colName, rdr[i].ToSafeString(), 50, EnumColumnType.String, colName));
                        }
                        lltc.Add(ltc);
                    }
                    rm.Trend = new TableViewModel { Grid = lltc };
                }
            }  
        }
        catch (Exception ex)
        {
            log.Error(MethodBase.GetCurrentMethod(), ex);
            return null;

        }
        await Task.WhenAll();
        return rm;
       // return lltc;
    }

however, stepping through the code, as soon as we hit any await, The application simply loads, and no further code is hit..

Any advice or recommendations for this would be greatly appreciated.

Upvotes: 1

Views: 9914

Answers (1)

GazTheDestroyer
GazTheDestroyer

Reputation: 21241

The async part is the DB I/O, meaning that while you are awaiting an open, or a read, your app is free to do other things rather than blocking on the DB.

await/async allows you to write code in a sequential manner even though parts may take a while. The code flows exactly as you would expect in sequence, the line after each await doesn't run until the awaited item has finished, but the current thread is unwound back up the stack so it can get on with other things.

If you want to do two things at once using await/async, then you need to wrap each one in a function that returns a Task just like traditional TPL. That way you can keep hold of the tasks WITHOUT awaiting their results until you want to.

Upvotes: 6

Related Questions