我在这种情况下:view image
空面板中堆叠有5个用户控件。
我有一个垂直菜单,其中有几个按钮,当我单击一个按钮时,我使用BringToFront()
来显示它们。
private void Button1_Click(object sender, EventArgs e)
{
tabRandom1.BringToFront();
}
每个usercontrol
包含datagridview
以及其他elements
,必须将这些数据与来自数据库的数据一起加载,但是我想如果我单击button1
,仅加载usercontrol1
的元素。
当我尝试时:
private async void UserControl1_Load(object sender, EventArgs e)
{
this.DataGridView1.DataSource = await GetDataAsync();
}
我收到@ er-shoaib例外:
there is already an open DataReader associated with tis connection which must be closed first.
我正在寻找加载活动用户控件元素的最佳方法
答案 0 :(得分:1)
您遇到的错误显然是您已经打开了DataReader
。
在一个连接中打开的DataReader
不能超过一个。
为了使您与数据库通信的代码更稳定,请使用using
编写代码,并且它将自动处理以下对象:
using(SqlConnection con = new SqlConnection("..."))
{
con.Open();
using(SqlCommand cmd = new SqlCommand("...", con))
{
using(SqlDataReader dr = cmd.ExecuteReader())
{
while(dr.Read())
// Do the things
}
}
// Do not need close since connection will be disposed
}
或者如果您为一个全班打开了一个连接(比如我认为您在那做过),只是不要将SqlConnection con = new Sql....
包裹在using
内,但是其他人都会做,并且您不会遇到任何麻烦不要忘记做connection.Close()
。
我一直在对SQL连接中的每个组件使用using
,但这并不影响我的性能。
以这种方式重新组织代码时,您将摆脱该问题,但一个建议是不要在有人打开表单时加载数据,因为您将加载5次,并且用户只能使用一种更好的创建方法,例如{{1 }}在您的UC内部,在您进行RefreshData()
之前,您还需要进行yourUserControl.BringToFront();
,这样,您仅在需要时才加载它,并且总是有一个新的,并且在需要时可以轻松地刷新数据任何地方。