1

I have created a supposed to be asynchronous method. And inside of that it has several await statements. I am calling this method (in another class) from the main method.

But it doesn't return the control back to the caller (main), to execute the next statement (to get more data), even though the operation takes long time to complete.

What is wrong here? Could it be something with the return statement? Or do I need to wrap the logic inside a Task?

internal async static Task<List<Cars>> GetCarsAsync()
        {
            var cars = new List<Cars>();

            try
            {
                using (var connection = new OracleConnection(ConfigurationManager.ConnectionStrings["KWC"].ConnectionString))
                {
                    await connection.OpenAsync(); //first await
                    logger.Info("Opened database connection.");

                    StringBuilder selectStatement = new StringBuilder(Properties.Settings.Default.SelectCarsView);

                    using (var command = connection.CreateCommand())
                    {
                        command.CommandText = selectStatement.ToString();
                        logger.Info("About to execute following query on database: {0}", command.CommandText);

                        using (var reader = await command.ExecuteReaderAsync()) //second await
                        {
                            logger.Info("Executed query: {0}", command.CommandText);

                            while (await reader.ReadAsync()) //third await
                            {
                                var car = new Car { model = reader.GetString(0) };
                                //more code
                                cars.Add(car);
                            }
                        }
                    }
                }

                return cars;
            }
            catch (OracleException ex)
            {
                logger.Fatal(ex.Message);
                throw;
            }
        }
static async Task Main(string[] args)
        {
            var getCarsTask = CarsManager.GetCarsAsync();
            var getSomethingElseTask = DummyManager.GetMoreDataAsync();
            // more similar tasks

            var cars = await getCarsTask;
            var moreData = await getSomethingElseTask;
            // more code
        }
KWC
  • 109
  • 1
  • 8
  • 2
    Is there an Exception thrown? – Crowcoder May 22 '20 at 11:48
  • 1
    How do you know that it isn't returning? `GetCarsAsync` will return at the first `await`. – Johnathan Barclay May 22 '20 at 11:49
  • there are no exceptions thrown. and I know that it is not returning according to the log. the first statement takes 20 minutes to fetch data. so it should have returned the control back to the main method to execute the next statement while waiting. but instead it returns when all the data is fetched. so it ran synchronously. – KWC May 22 '20 at 11:56
  • Add a `Console.WriteLine(DateTime.Now);` before and after `var getCarsTask = CarsManager.GetCarsAsync();`. – Johnathan Barclay May 22 '20 at 12:02
  • You are only catching an `OracleException` and not catching any in `Main`. I don't think you can be sure there are no Exceptions. This seems unlikely, but the Oracle API you are using might might expose "async" methods that are not actually async. It happens. You might try abstracting your data access so that you can inject a mock and see if it flows as you expect that way. – Crowcoder May 22 '20 at 12:02
  • 3
    If [this is what you are using](https://stackoverflow.com/questions/29016698/can-the-oracle-managed-driver-use-async-wait-properly/29034291#29034291) then I think my guess was correct. horrOracle is not actually async. – Crowcoder May 22 '20 at 12:06
  • Yes, I am using Oracle.ManagedDataAccess. This is indeed horrible. Thanks for the answer. – KWC May 22 '20 at 12:10

0 Answers0