6

I have following code. the call to connection.OpenAsync() quits the program without any exception. Even the finally on the caller method is not invoked. program is targetting .NET45 Any idea?

Update: Here is the parent code that works with .Wait(). It quits without .Wait() in parent code when connection.OpenAsync() is called in the child method below.

        static void Main(string[] args)
        {
            UpdateSqlDatabase updateSqlDatabase = new UpdateSqlDatabase(args);
            updateSqlDatabase.UpdateDatabaseSchemaAsync().Wait();
        }

After a series of async method calls:

    public async Task<T> ExecuteQueryAsync<T>(string connectionString, string commandText, IDictionary<string, object> parameters, Func<SqlDataReader, T> rowMapFunc)
    {
        using (var connection = new SqlConnection(connectionString))
        {
            try
            {
                await connection.OpenAsync();
            }
            catch (Exception ex)
            {
            }

            SqlCommand command = connection.CreateCommand();
            command.CommandType = CommandType.Text;
            command.CommandText = commandText;
            if (parameters != null)
            {
                foreach (var item in parameters)
                {
                    command.Parameters.AddWithValue(item.Key, item.Value);
                }
            }

            SqlDataReader reader = await command.ExecuteReaderAsync();
            T retObj = default(T);

            while (await reader.ReadAsync())
            {
                retObj = rowMapFunc(reader);
            }

            return retObj;
        }
    }
5
  • Don't do this: catch (Exception) {}, you're shooting yourself in the foot. What are the exception details, after all? Commented Feb 13, 2014 at 2:51
  • when i debug the code never reaches. I added that catch to see what was wrong (not going to be part of my code). Essentially as i debug on executing connection.OpenAsync() just quits the program. i.e. the console app just quits without any error/exception. The catch block is never hit in this code. Commented Feb 13, 2014 at 2:55
  • Change your code like this: pastebin.com/ZmsA3k4g. Set a break point on "A", "B", "C", "D" lines and run under debugger. What breakpoints get hit? Commented Feb 13, 2014 at 3:04
  • A and B are hit. C and D did not Commented Feb 13, 2014 at 3:13
  • Then check the Windows Event Log as @JAnderson suggests. Commented Feb 13, 2014 at 3:14

3 Answers 3

4

So the issue was that in the code I had chain of async calls but the parent (main) method was not async and did not have await causing the program to quit when Async was called by one of the child method. I added .Wait() to the call to the async method from main method (which is sync) and it worked fine.

Thanks!

Sign up to request clarification or add additional context in comments.

5 Comments

Having a .Wait() at the root of a async chain is almost never the correct thing to do and can often cause your program to lock up in a deadlock! Either you should write your code without any async or the function that calls Wait() should be async and await on the task instead of .Wait() on it. If you could, updated your question and show the initial function that you added the .Wait() to, we can help you figure out which option would be the correct one to use.
Ok, from the code you added, you are on the "Don't use Async" side. You are using a console application, there is no reason to be using async code. All it is doing is adding overhead and slowing down your code. See if there is a updateSqlDatabase.UpdateDatabaseSchema() version of the function, you should use that instead in your situation.
i added the code in original post. Thanks for your help.
Async code is only useful if you have other work to do while you wait. In UI applications it lets the UI go back to processing new mouse clicks and repainting the screen, for ASP.NET programs it returns the thread to the threadpool so more requests can come in. In a console application like yours there is no other work "waiting to be done" so just run the code synchronously and don't pay for the overhead of doing async.
I had just typed out some quick tests and forgot to make calls to my async business layer with await and had the same behavior. This was a quick reminder, thanks.
3

The msdn documentation states this:

Exceptions will be propagated via the returned Task. If the connection timeout time elapses without successfully connecting, the returned Task will be marked as faulted with an Exception. The implementation returns a Task without blocking the calling thread for both pooled and non-pooled connections.

So, the proper use of connection.OpenAsync() will rather look something like this

using(var connection = new SqlConnection(connectionString))
{
    var connectionTask = connection.OpenAsync();
    // other code goes here
    Task.WaitAll(connectionTask); //make sure the task is completed
    if(connectionTask.IsFaulted) // in case of failure
    {
       throw new Exception("Connection failure", connectionTask.Exception);
    }
    // rest of the code
 }

Comments

0

Possibly the OpenAsync() method is calling Enviroment.FailFast(), which will cause any finally blocks to not execute. This usage is logged to the Event Log though, so you should be able to check if there is anything there.

For more details, see the following http://msdn.microsoft.com/en-us/library/ms131100(v=vs.110).aspx

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.