Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Task when all, connection is closing

I'm trying to execute multiple SqlDataReaders using Task.WhenAll. But when the tasks are awaited I get

"System.InvalidOperationException: Invalid operation. The connection is closed".

Creation of tasks:

        List<Task<SqlDataReader>> _listTasksDataReader = new List<Task<SqlDataReader>>();
        _listTasksDataReader.Add(GetSqlDataReader1(10));
        _listTasksDataReader.Add(GetSqlDataReader2(10));
        SqlDataReader[] _dataReaders = await Task.WhenAll(_listTasksDataReader);

My "SqlDataReader" methods:

    public Task<SqlDataReader> GetSqlDataReader1(int recordCount)
    {
        using (var sqlCon = new SqlConnection(ConnectionString))
        {
            sqlCon.Open();
            using (var command = new SqlCommand("sp_GetData", sqlCon))
            {
                command.Parameters.Clear();
                command.Parameters.Add(new SqlParameter("@recordCount", recordCount));
                command.CommandType = System.Data.CommandType.StoredProcedure;
                return command.ExecuteReaderAsync();
            }
        }
    }

Shouldn't the database connections be opened when the Task.WhenAll is executed or am I missing something?

like image 691
AsusT9 Avatar asked Sep 23 '16 13:09

AsusT9


People also ask

What is a continuation task?

In the Task Parallel Library, the same functionality is provided by continuation tasks. A continuation task (also known just as a continuation) is an asynchronous task that's invoked by another task, known as the antecedent, when the antecedent finishes.

What happens when SQL connection is closed?

If connection pooling is off, the transaction is rolled back after SqlConnection. Close is called. Transactions started through System. Transactions are controlled through the System.

What is ContinueWith c#?

The ContinueWith function is a method available on the task that allows executing code after the task has finished execution. In simple words it allows continuation. Things to note here is that ContinueWith also returns one Task. That means you can attach ContinueWith one task returned by this method.

Does using close the connection?

Answers. Yes. When the using block ends, the connection automatically closes (That is what IDisposable is for). So, do not close the connection explicitly.


2 Answers

It is possible to pass a CommandBehavior.CloseConnection to the ExecuteReaderAsync. Then the connection will remain open until the returned datareader object is closed: see MSDN here and here. In that case, the SqlConnection does not need to be in a using statement.

Like this:

public Task<SqlDataReader> GetSqlDataReader1(int recordCount)
{
    var sqlCon = new SqlConnection(ConnectionString);
    sqlCon.Open();

    using (var command = new SqlCommand("sp_GetData", sqlCon))
    {
        command.Parameters.Clear();
        command.Parameters.Add(new SqlParameter("@recordCount", recordCount));
        command.CommandType = System.Data.CommandType.StoredProcedure;
        return command.ExecuteReaderAsync(CommandBehavior.CloseConnection);
    }
}
like image 81
Frits Avatar answered Oct 06 '22 01:10

Frits


am I missing something?

You're trying to get a SqlDataReader that doesn't have an underlying connection? I don't think that will work well. What happens as you read from the reader? The connection is already closed.

So, you probably just need to read the actual data before closing the connection:

public async Task<List<T>> GetData1(int recordCount)
{
    using (var sqlCon = new SqlConnection(ConnectionString))
    {
        sqlCon.Open();
        using (var command = new SqlCommand("sp_GetData", sqlCon))
        {
            command.Parameters.Clear();
            command.Parameters.Add(new SqlParameter("@recordCount", recordCount));
            command.CommandType = System.Data.CommandType.StoredProcedure;

            var result = new List<T>();
            var reader = await command.ExecuteReaderAsync();
            // TODO: use `reader` to populate `result`
            return result;
        }
    }
}
like image 30
Stephen Cleary Avatar answered Oct 05 '22 23:10

Stephen Cleary