【发布时间】:2017-12-22 03:31:26
【问题描述】:
我有一个 C# 中的 Windows 窗体应用程序,其中一个按钮运行如下代码:
private void aCertainButton_Click(object sender, EventArgs e)
{
if (folderFinder.ShowDialog() == DialogResult.OK)
{
if (openConnection())
{
foreach (Thingy stuff in aCertainCollection)
{
string sqlCommandString = "SELECT COUNT(*) FROM thatTable WHERE someField = " + stuff.property + ";";
try
{
MySqlCommand count = new MySqlCommand(sqlCommandString, connection);
int rowCount = 0;
object o = count.ExecuteScalar();
if (o != null)
{
rowCount = int.Parse(o.ToString());
}
if (rowCount == 1)
{
MySqlCommand cmd = new MySqlCommand("SELECT * FROM thatTable WHERE someField = " + stuff.property + ";", connection);
MySqlDataReader reader = cmd.ExecuteReader();
//Processing stuff from the reader here
reader.Close();
reader.Dispose();
}
}
catch (MySqlException mex)
{
Console.WriteLine(mex.Message);
}
}
closeConnection();
}
}
}
每当我运行应用程序时,我都会遇到以下异常:“已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭它。”
但不应该。我在这段代码中使用了 1 个阅读器,并且没有其他任何东西异步运行。如您所见,我关闭阅读器并在循环中的每次迭代后打开一个新阅读器。我在应用程序的初始化中使用了与同一连接关联的读取器,但是当来自它的数据处理完成后,我将其关闭并处理掉它。
如果有人能帮我解开这个谜团,我将不胜感激,谢谢。
【问题讨论】:
-
您的代码可能存在 SQL 注入漏洞。请阅读并使用参数化查询。
-
看起来您正在使用全局连接。在您点击此代码中的第一个阅读器之前,是否有可能打开阅读器?我强烈建议您根据需要创建连接,并确保将所有一次性对象放入
using语句中。 msdn.microsoft.com/en-us/library/… -
@Daniel Mann 谢谢,但这是一个小型实用应用程序,我只为自己编写。一切都是完全本地的。我认为问题也一定是本地的,而不是来自攻击者。
-
@juharr 一开始我也是这么想的,但是我浏览了代码,唯一的其他阅读器正在初始化,并且被正确关闭。
-
如果在您“处理内容”时尝试在您的尝试中产生异常,那么您将使阅读器保持打开状态,并且在下一个循环中它会抱怨它。