Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Close() or Dispose() throws if Close() has already been called #620

Closed
Timovzl opened this issue Mar 19, 2019 · 6 comments · Fixed by #623
Closed

Close() or Dispose() throws if Close() has already been called #620

Timovzl opened this issue Mar 19, 2019 · 6 comments · Fixed by #623
Labels

Comments

@Timovzl
Copy link

Timovzl commented Mar 19, 2019

When the data reader is disposed or closed after it has already been closed, it throws. This is undesirable and sometimes even problematic.

A disposable object should always (generally) be disposed. If one part of the process deems it correct to close the reader, but disposing it is not its responsibility, then another part of the process must be able to dispose it.

The above appears in particular when ExecuteReader(CommandBehavior.CloseConnection) is used, where disposing the reader closes the connection. The connection should still be disposed, but particularly if a class receives a reader through its constructor (as is my case), it cannot know if that reader will close its connection, so it has to dispose it.

@bgrainger
Copy link
Member

Do you have sample code to reproduce the problem? I tried the following, without success:

using (var connection = new MySqlConnection("..."))
{
	connection.Open();
	using (var command = new MySqlCommand("SELECT 1;", connection))
	using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
	{
		while (reader.Read()) { }
		reader.Close();
		reader.Dispose();
		reader.Close();
	}
}

@bgrainger bgrainger added the waiting for answer Needs more information from the bug reporter label Mar 19, 2019
@Timovzl
Copy link
Author

Timovzl commented Mar 20, 2019

Bugger, it must be more obscure.

I am investigating. In doing so, I have found an issue where the connection should have been closed, but is still open. I am not entirely sure if this is the core of the original issue. My guess is it's not, and I'm still looking for that, but it might be.

See the comments where I OpenAsync() the second time. This throws "Cannot Open when State is Open".

using (TransactionScope outerScope = null) //CreateTransactionScope()) // Same effect as when using inner scope below
using (var connection = new MySqlConnection("Server=ip;Uid=uid;Pwd=pwd;TreatTinyAsBoolean=False;UseAffectedRows=True;SslMode=None;UseXaTransactions=False;"))
{
	using (var innerScope = CreateTransactionScope())
	{
		using (var command1 = new MySqlCommand("SELECT 1"))
		using (var command2 = new MySqlCommand("SELECT 2"))
		{
			command1.Connection = connection;
			command2.Connection = connection;

			await connection.OpenAsync();
			using (var reader = await command1.ExecuteReaderAsync(CommandBehavior.CloseConnection, CancellationToken.None))
			{
				while (await reader.ReadAsync())
				{
					Console.WriteLine(reader.GetValue(0));
				}
			} // Disposal should close connection (at least from a functional perspective)

			await connection.OpenAsync(); // Should be able to "reopen" connection (technically the same underlying open connection, because of non-XA)
			using (var reader = await command2.ExecuteReaderAsync(CommandBehavior.CloseConnection, CancellationToken.None))
			{
				while (await reader.ReadAsync())
				{
					Console.WriteLine(reader.GetValue(0));
				}
			}
		}
	}
}

@bgrainger bgrainger removed the waiting for answer Needs more information from the bug reporter label Mar 21, 2019
@Timovzl
Copy link
Author

Timovzl commented Mar 21, 2019

I forgot to mention that the original exception on disposal was "Expected this MySqlConnection to have no ServerSession, but it was already attached". I have not been able to reproduce it yet, and will wait for what you discover based on my previous post.

@bgrainger bgrainger added the bug label Mar 21, 2019
@bgrainger
Copy link
Member

Thanks; I can reproduce the problem now. I agree with your assessment that "Disposal should close connection (at least from a functional perspective)".

bgrainger added a commit that referenced this issue Mar 25, 2019
This tests a variation of the failing code that reproduces #620.
@Timovzl
Copy link
Author

Timovzl commented Mar 29, 2019

Works like a charm. :)

@bgrainger
Copy link
Member

Fixed in 0.51.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging a pull request may close this issue.

2 participants