Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SqlConnection closes unexpectedly inside using statement

I have an SQL connection service that I'm trying to build. I essentially do this:

var data = await GetDataFromFlatFilesAsync(dir).ConfigureAwait(false);
using (var conn = new SqlConnection(MyConnectionString))
{
    try
    {
        conn.Open();
        var rw = new SqlReaderWriter(conn);

        await DoStuffWithSqlAsync(rw, data).ConfigureAwait(false);
     }
     catch (Exception ex)
     {
         // Do exceptional stuff here
     }
}

DoStuffWithSqlAsync operates like this:

private async Task DoStuffWithSqlAsync(SqlReaderWriter rw, IEnumerable<Thing> data)
{
    await Task.WhenAll(data.Select(rw.RunQueryAsync)).ConfigureAwait(false);
}

And RunQueryAsync operates like this:

public async Task RunQueryAsync<T>(T content)
{
    // _conn is assigned to in the constructor with conn
    try
    {
        var dataQuery = _conn.CreateCommand();
        dataQuery.CommandText = TranslateContentToQuery(content);
        await dataQuery.ExecuteNonQueryAsync().ConfigureAwait(false);
    }
    catch (Exception ex)
    {
        // Do exceptional stuff here
    }
}

The problem I'm running into is that DoStuffWithSqlAsync continuously fails with a System.InvalidOperationException stating that conn is in a closed state. However, when I examine the stack trace, I find execution is still inside the using statement. I also know that conn is not closed anywhere inside this operation as execution must necessarily return to the statement and any exception inside should be bubbled up to the enclosing try-catch and caught there. Additionally, the connection is pooled and MARS is enabled. So then, why is this being closed?

UPDATE: It was pointed out that I hadn't opened my connection. I have done so but the error persists except now _conn.State is set to Open.

UPDATE: I was having an issue wherein I used await conn.OpenAsync.ConfigureAwait(false); which would not block execution. So, when I tried to connect to the database, I would get an exception stating that the connection state was closed but by that point it would have opened so on examination it would show Open. It was suggested that I make the calling method async void but as the application is console, not UI I don't think that will help. I have since reverted to using the synchronous method.

like image 242
Woody1193 Avatar asked Jan 04 '18 15:01

Woody1193


People also ask

Does using automatically close SqlConnection?

The connection is automatically closed at the end of the using block.

Does disposing SqlConnection close connection?

If the SqlConnection goes out of scope, it won't be closed. Therefore, you must explicitly close the connection by calling Close or Dispose . Close and Dispose are functionally equivalent. If the connection pooling value Pooling is set to true or yes , the underlying connection is returned back to the connection pool.

What is the use of SqlConnection in C#?

A SqlConnection object represents a unique session to a SQL Server data source. With a client/server database system, it is equivalent to a network connection to the server. SqlConnection is used together with SqlDataAdapter and SqlCommand to increase performance when connecting to a Microsoft SQL Server database.

Does using statement close SQL connection C#?

The using statement handles the disposal and subsequent closing of my objects for me. Even if an exception is thrown, as soon as execution leaves the using block the DIspose method of the object is invoked under the covers. For objects like the SqlConnection, this also closes the connection too.


1 Answers

You just need to open the connection:

try
{
  conn.Open() //<--add this
  var rw = new SqlReaderWriter(conn);
  await DoStuffWithSqlAsync(rw, data).ConfigureAwait(false);
}
like image 119
apomene Avatar answered Sep 21 '22 23:09

apomene