I am having issues closing MySqlDataReader. It seems as though the .Close() command hangs. Does anyone know how to get around this?
static void Main(string[] args)
{
MySqlConnection cn = new MySqlConnection("SERVER=svr;DATABASE=db;UID=uid;PASSWORD开发者_运维问答=pwd;");
cn.Open();
MySqlCommand cmd = new MySqlCommand("SELECT * FROM SOMETABLE", cn);
MySqlDataReader dr = cmd.ExecuteReader();
int ii = 0;
while (dr.Read())
{
Console.WriteLine(dr.GetValue(1).ToString());
if (ii++ > 10) break;
}
dr.Close();
cn.Close();
}
**NOTE: I've changed the code to not use static objects. It still hangs on the .Close()
I'd use the Using keyword:
Using dr As MySqlDataReader = cmd.ExecuteReader()
...
End Using
(sorry for the VB syntax)
edit: you may get faster Close operations if you call Cancel on the command, before calling Close. Anyhow the behaviour of your Close is a strange issue.
dr.Cancel();
dr.Close();
cn.Close();
edit2: doing more research I've found that the problem will be solved if you call Cancel and the reason is your "break" instruction. Source: http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=610
"The reason for the program hanging is that the SqlDataReader.Close method fills in the values for output parameters, return values and RecordsAffected. If you try to close the reader before it’s read all of the records, Close tries to read all the data and fill out those values. If you don’t care about those values—and you likely don’t if you’re breaking out of the read loop, you should cancel the underlying command before calling Close. In the above case, what you want to do is call command.Cancel just before exiting the loop."
This might be related to sharing static connection, command and reader objects. Even if that's not the cause of this particular problem it's a very good idea not to do it.
You should use local connection, command and reader variables. Create them as late as possible; close them as early as possible.
Try this instead:
static void Main(string[] args)
{
using (var conn = new MySqlConnection("..."))
using (var cmd = new MySqlCommand("...", conn))
{
conn.Open();
using (MySqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
// do something
}
}
}
}
精彩评论