.Net客户端超时
本文关键字:超时 客户端 Net | 更新日期: 2023-09-27 18:27:25
在我的Windows应用程序中,我尝试使用以下代码连接到SQL Server 2008:
SqlConnection connection = new SqlConnection(Properties.Settings.Default.KargarBandarConnectionString);
SqlCommand command = new SqlCommand("Select IsAdmin from Users where UserName=@UserName And Password=@Password", connection);
SqlDataReader dataReader = null;
command.Parameters.AddWithValue("@UserName", UserNameTextBox.Text.Trim());
command.Parameters.AddWithValue("@Password", PasswordTextBox.Text);
try
{
connection.Open();
dataReader = command.ExecuteReader();
if (dataReader.HasRows)
{
while (dataReader.Read())
{
IsAdmin = dataReader.GetBoolean(0);
}
this.DialogResult = DialogResult.OK;
}
else
{
FMessageBox.ShowWarning("error");
UserNameTextBox.Focus();
}
}
catch (Exception ex)
{
if (progressForm != null)
progressForm.Close();
FMessageBox.ShowError(ex.Message);
}
finally
{
if (dataReader != null)
{
dataReader.Close();
dataReader.Dispose();
}
if (connection != null)
{
connection.Close();
connection.Dispose();
}
}
一切正常,但有时我会得到以下错误:
超时已过期。在获得来自池的连接。。。
如何解决这个问题?
出现此异常的原因是您已经耗尽了连接池和应用程序中的"可用"连接数。
每次打开连接时,如果可能,都会从连接池中提取一个连接,如果不可能,则会创建一个新连接。
然而,为了防止连接的快速使用,存在100的限制(我认为这是可配置的),如果您尝试同时使用100个以上的连接,代码将而不是创建新的连接,而是坐下来等待一个连接返回到池中,在这种情况下,如果连接时间过长,则会超时。
因此,对于您展示的代码的特定示例,我会:
在之前关闭连接我向用户显示错误消息
但是,除非100个用户同时看到错误消息并将其留在那里,否则您显示的代码不太可能是导致此问题的原因。
除此之外,我会检查整个应用程序,并确保您在其他地方没有任何连接泄漏。
这种特殊类型的异常可能发生在一个地方,即使问题发生在其他地方。示例:一个报告每次运行时都会泄漏一个打开的连接,如果你成功地运行了100次,然后有人试图登录,则异常出现在登录表单中。
如果您:
- 泄漏连接(让GC处理而不是处理它们)
- 只是发生了太多事情,以至于池水都用完了
第一种是最常见的,我预计这在很大程度上与错误处理过于复杂的事实有关。这使得它很容易被错过,也很难发现你错过了它。显示的代码看起来不错,但最好对所有IDisposable
元素使用using
块,而不是finally
。而且在显示消息框等模态内容时不要保持连接,除非之后需要连接。坦率地说,通过干净地分离UI和数据访问代码,可以获得很多好处,这样就不会有在数据库查询中间粘贴message-box的诱惑。
然而!明确地说,我认为这段代码是其他占用连接的代码的受害者。请查看您的其他数据访问代码以了解原因。
重构代码,使其看起来像这样。实现using
块。这里的其他答案非常重要,一定要理解它们。
bool res=false;
try
{
using(var connection = new SqlConnection(Properties.Settings.Default.KargarBandarConnectionString))
using(var cmd = conn.CreateCommand())
{
cmd.commandText = "Select IsAdmin from Users where UserName=@UserName And HashedAndSaltedPassword=@PwdHash";
cmd.Parameters.AddWithValue("@UserName", UserNameTextBox.Text.Trim());
cmd.Parameters.AddWithValue("@PwdHash", SaltAndHash(PasswordTextBox.Text));
connection.Open();
var result = cmd.ExecuteScalar();
if (result!=null)
{
res=bool.Parse(result);
this.DialogResult = DialogResult.OK;
}
}
}
catch (Exception ex)
{
if (progressForm != null){progressForm.Close();}
FMessageBox.ShowError(ex.Message);
}
if(res==false)
{
FMessageBox.ShowWarning("error");
UserNameTextBox.Focus();
}