C#  winform程序在公司测试没有任何问题,到客户现场安装老是弹出一个错误提示"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.",网上说是数据库连接没关闭,可是我组查了代码,每一个连接数据库的类中都关闭了数据库连接,都用了 using (SqlConnection con = SqlHelper.GetConnection())
                        try
                {
                    con.Open();
                    string cmdSelect = "select room_id,bed_Name,sickName,sex,NurLevel,illState,Cared,Wcfs from BASE_BED where hushisiteID='" + Init.GetHushisiteIdByIp() + "'order by room_id,bed_Name";
                    using (SqlCommand cmd = new SqlCommand(cmdSelect, con))
                    {
                        using (SqlDataReader dr = cmd.ExecuteReader())
                        {....
.}
}
}这类语法,可是软件运行时间久了还是会出现上面的错误,请教各位高手。

解决方案 »

  1.   

    用的什么数据库?
    不要用SQL Server
      

  2.   


    啊,不用sqlserver数据库,这与用什么数据库有关系吗,公司用的就是sqlserver数据库啊。
      

  3.   

    网速问题或者是数据量太大,超出的sql的连接时间。可以再Command中加入时间参数控制
    http://www.jb51.net/article/23614.htm
      

  4.   

    using (SqlCommand cmd = new SqlCommand(cmdSelect, con))
      {
      using (SqlDataReader dr = cmd.ExecuteReader())
      {....
    这中写法有问题,用try..catch..finaly代替试试
      

  5.   

    你都说了是winform程序,
    要是客户端没有连网或者网速问题或者查询数据量过多
    就挂了,
    或者在客户端也装sqlserver,
    这都不合适,
    最好用轻量数据库,
    如ACCESS,sqlite等
      

  6.   


    有问题?不是吧, using (SqlConnection con = SqlHelper.GetConnection())
                {
                    try
                    {
                        con.Open();
                        string cmdSelect = "select room_id,bed_Name,sickName,sex,NurLevel,illState,Cared,Wcfs from BASE_BED where hushisiteID='" + Init.GetHushisiteIdByIp() + "'order by room_id,bed_Name";
                        using (SqlCommand cmd = new SqlCommand(cmdSelect, con))
                        {
                            using (SqlDataReader dr = cmd.ExecuteReader())
                            {
                                while (dr.Read())
                                {
                                    roomID = Convert.ToString(dr["room_id"]);
                                    bedName = Convert.ToString(dr["bed_Name"]);
                                    sickName = Convert.ToString(dr["sickName"]);
                                    sex = Convert.ToString(dr["sex"]);
                                    nurselevel = Convert.ToString(dr["NurLevel"]);
                                    illstate = Convert.ToString(dr["illState"]);
                                    cared = Convert.ToString(dr["Cared"]);
                                    wcfs = Convert.ToString(dr["Wcfs"]);
                                    roomName = GetRoomName(roomID);
                                    bedinfolist.Add(roomName + "," + bedName + "," + sickName + "," + sex + "," + nurselevel + "," + illstate + "," + cared + "," + wcfs);
                                }
                                dr.Close();
                            }
                        }
                          return bedinfolist;
                    }
                    catch(Exception ex){
                        MessageBox.Show(ex.Message);
                        return null;
                    }
                    finally{
                    con.Close();
                    con.Dispose();
                    }
                }
              用了using,按理说不用显示关闭就行,自动打开关闭的,上面是我查询数据库的代码,在using里面用了try{}catch(){}还显示在finally里面关闭了数据库连接对象,还是出现此错误,我已经无语了。
      

  7.   


    不行啊,都用了sqlserver数据库。
      

  8.   

    那是因为try里面出错(可能是网速问题),会跳到catch,而你的con.Close();放在try里面,所以没有执行,在执行另外一个Open的时候就会出错。
    解决办法是:把con.Close();放在try...catch...语句块的后面
      

  9.   


    额,我没放到try里面,我放到finally{
      con.Close();
      con.Dispose();
      }
    里面在。
      

  10.   

    为什么用了using还要用try呢?
      

  11.   


    这个不影响吧,try{}只是捕获错误,并且我的try{}用在using外面,可以捕获using里面的错误。
      

  12.   

    把所有的数据量不大的请求的地址的DataReader全部去除,改成 DataSet,你的问题就解决了.
      

  13.   

    使用了DataReader,你即使离开Using语句块,连接还是被保持着,否则DataReader怎么读取数据?
      

  14.   

    (SqlDataReader dr = cmd.ExecuteReader())  
    对 这里 少个参数
      using (SqlDataReader readerTemp = cmdTemp.ExecuteReader(CommandBehavior.CloseConnection))
      

  15.   

    关闭DATAREADER的时候 关联的 connection 并没有被关闭
      

  16.   

    你先看看配置,上面都说了是pool连接max了,最大是多少?现在你们多少人在用?有多少没有关闭的把它释放了。然后把你的程序改一下。。最后加个判断 if没关闭 就关闭。
    这种程序,每次开一个连接,很烦,你们定义的主类,前面只需要一个conn就够了,把这个当参数传进来。。通一在最外层实行监控关闭报日志等操作。
      

  17.   


    在高访问并发下,即使你使用完毕,立即就关闭这个DataReader对象, 依然会有连接过多的错误, 这可能是因为GC的原因,但是如果你是用DataSet,则绝不会有这种问题,建议楼主可以做个Test.
    写个循环(调用几万次),不断调用某个用DataReader读数据的方法,比较DataSet,看看效果
      

  18.   

    最简单的办法:把所有的con.Open();换成下面这句if (con.State==ConnectionState.Closed) con.Open();
      

  19.   

    如果连接字符串里没有特殊指定
    Max Pool Size 100 The maximum number of connections allowed in the pool.
    Min Pool Size 0 The minimum number of connections maintained in the pool.100应该足够了。SqlConnection.ConnectionTimeout Property
    Type: System.Int32
    The time (in seconds) to wait for a connection to open. The default value is 15 seconds.15秒够不够?其它地方我个人看不出有什么问题。lz解决了上来说一下是什么问题。
      

  20.   


    这个?可是我程序中大部分都是用的datareader读取数据的,全部改成dataset不太现实啊。
      

  21.   

    WEB.config 里面:在数据库连接加 Max Pool Size = 512;server=local;uid=;pwd=;database=2004;Max Pool Size = 512;">一劳永逸。
      

  22.   

    呵呵,我的数据库连接字符串是根据用户的配置加密保存在文件中的,没用到app.config,我在晚上查了,说是用这个有弊端Max Pool Size = 512,影响程序性能。
      

  23.   


    这个为什么 Max Pool Size = 512这个属性要设置两次了?
      

  24.   

    我在网上还查了一种可能,就是说客户电脑没打补丁,比如sp4,sp3等,不知道会不会有这个可能。
      

  25.   

    肯定不是try catch之类的问题,那只是捕获异常,using会自动释放资源啊
      

  26.   


    把Connection放在using里,会释放连接到Connection pool的。我也一直这么用的。我觉得lz在什么地方没有用using。
      

  27.   

    我能确定所有的地方都用了using.
      

  28.   

    问题解决了,原因是虽然关闭了connection对象,但是没有关闭datareader对象。
    (SqlDataReader dr = cmd.ExecuteReader())   
    对 这里 少个参数
      using (SqlDataReader readerTemp = cmdTemp.ExecuteReader(CommandBehavior.CloseConnection)) 我将所有的读取数据库的方法都改成
     public string GetRoomName(string roomID)
            {
                using (SqlConnection con = SqlHelper.GetConnection())
                {
                    try
                    {
                        string roomname = "";
                        if (con.State == ConnectionState.Closed)
                        {
                            con.Open();
                        }
                        string cmdSelect = "select room_name from BASE_ROOM where hushisiteID='" + Init.GetHushisiteIdByIp() + "' and room_id='" + roomID + "'";
                        using (SqlCommand cmd = new SqlCommand(cmdSelect, con))
                        {
                            using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                            {
                                while (dr.Read())
                                {
                                    roomname = Convert.ToString(dr["room_name"]);
                                }
                                dr.Close();
                            }
                            return roomname;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        return "";
                    }
                    finally
                    {
                        if (con.State == ConnectionState.Open)
                        {
                            con.Close();
                            con.Dispose();
                        }
                    }
                }
               
            } 这样,问题解决。谢谢各位的回答