-
Notifications
You must be signed in to change notification settings - Fork 345
-
IT WAS
public SQLResult Query(PreparedStatement stmt)
{
try
{
var connection = new MySqlConnection(_connectionInfo.ConnectionString);
connection.Open();
using MySqlCommand cmd = connection.CreateCommand();
cmd.CommandText = stmt.CommandText;
foreach (var parameter in stmt.Parameters)
cmd.Parameters.AddWithValue("@" + parameter.Key, parameter.Value);
return new SQLResult(cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection));
}
catch (MySqlException ex)
{
HandleMySQLException(ex, stmt.CommandText, stmt.Parameters);
return new SQLResult();
}
}
--------------------------
public class SQLResult
{
MySqlDataReader _reader;
public SQLResult() { }
public SQLResult(MySqlDataReader reader)
{
_reader = reader;
NextRow();
}
~SQLResult()
{
_reader = null;
}
public bool NextRow()
{
if (_reader == null)
return false;
if (_reader.Read())
return true;
_reader.Close();
return false;
}
}
IT BECAME
public class SQLResult : IDisposable
{
MySqlDataReader _reader;
public SQLResult() { }
public SQLResult(MySqlDataReader reader)
{
_reader = reader;
if (!NextRow())
{
Dispose();
}
}
public bool NextRow()
{
return _reader.Read();
}
public void Dispose()
{
if (_reader != null)
{
_reader.Close();
_reader = null;
}
}
}
Beta Was this translation helpful? Give feedback.
All reactions
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling
The problem was about pool doesn't create a new reader after 2.3.х because it doesn't close current connection since now. (And it seems that now, being empty, the Reader itself closes and, together with the connection, passes into other hands without warning.)
And the stupid idea (maybe not) was using reader.Read() at creation reader's wrapper without any processing callback's bool value.
So I added in reader's wrapper the varification of this boolean value, and made it close the reader, and made link of it to be equal null.
Replies: 3 comments 4 replies
-
Might possibly be caused by #1277?
You haven't shown any relevant code AFAICT. How is MySqlBase<T>.Query
implemented? Are you caching MySqlDataReader
objects after disposing them?
Beta Was this translation helpful? Give feedback.
All reactions
-
It seems to me that the problem may have been caused by this update, but it is definitely not due to something wrong in the code - otherwise I would have received an ObjectDisposedException
Beta Was this translation helpful? Give feedback.
All reactions
-
Beta Was this translation helpful? Give feedback.
All reactions
-
~SQLResult() { _reader = null; }
This code snippet is an enormous red flag. It has almost never been necessary to write a finalizer since .NET Framework 2.0 (almost 20 years ago); see https://joeduffyblog.com/2005/12/27/never-write-a-finalizer-again-well-almost-never/. It's also completely unnecessary to set a field (_result
) to null
because that will simply happen implicitly when the object is garbage-collected (which, ironically, is delayed by the presence of a finalizer).
The checks against if (_reader == null)
when that can never be true (if the snippet you pasted is the entire class implementation) are another red flag.
The problem is almost certainly caused by misuse of the MySqlConnector API in your code. v2.2.7 must have permitted it, but v2.3.1 is "stricter" (in some sense) by requiring correct API use in order to return correct data. (In order to facilitate extremely high-performance code, MySqlConnector does not include explicit checks for all kinds of API misuse, so the outcome may be incorrect data rather than an exception.)
How is _connectionInfo.GetConnection();
implemented? Is that handing out (and reusing) the same connection? If so, that's probably the problem. If it's creating a new MySqlConnection
, then you're leaking MySqlConnection
objects, which is a different bug.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
Thank you, I changed it, but it doesnt help it
Beta Was this translation helpful? Give feedback.
All reactions
-
What does the SetQuery
method do? How is _LoadMail
called with its two SQLResult
objects? Is SQLResult
IDisposable
? Who cleans up the MySqlDataReader
that SQLResult
has when it's done?
Beta Was this translation helpful? Give feedback.
All reactions
-
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling
The problem was about pool doesn't create a new reader after 2.3.х because it doesn't close current connection since now. (And it seems that now, being empty, the Reader itself closes and, together with the connection, passes into other hands without warning.)
And the stupid idea (maybe not) was using reader.Read() at creation reader's wrapper without any processing callback's bool value.
So I added in reader's wrapper the varification of this boolean value, and made it close the reader, and made link of it to be equal null.
Beta Was this translation helpful? Give feedback.