我不断收到此错误:“阅读器关闭时调用读取无效”

Posted

技术标签:

【中文标题】我不断收到此错误:“阅读器关闭时调用读取无效”【英文标题】:I keep getting this error: "Invalid attempt to call Read when reader is closed" 【发布时间】:2011-02-06 10:40:05 【问题描述】:

这是我的代码,我关闭并打开阅读器,但它仍然无法正常工作。几个线程可以同时访问这个函数,但是有一个锁。它在开始时工作了几次,但迟早我会在

处收到异常“读取器关闭时调用读取无效”
private IList<BursaUser> GetUsers(SqlCommand cmd)

 IList<User> users = new List<User>();
 User user;
 lock (thisLock)
  
      SqlDataReader dr = null;

       try
       
           Conn.Open();
           dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
           while (dr.Read())
            
                user = new User
                
                    UserId = Convert.ToInt32(dr["WorkerNum"]),
                    CompanyName = dr["CompanyName"].ToString(),
                     WorkerName = dr["WorkerFirstName"] + " " + dr["WorkerFamilyName"],
                                      Phone = dr["Phone"].ToString()
                                  ;
                       if (dr["QueueNum"] != null && dr["QueueNum"] != DBNull.Value)
                       
                           user.Queue = new Queue
                            
                                  HasAlreadyEntered =
                                   dr["flgAppear"] != null && dr["flgAppear"].ToString() == "Y",
                                   IsFromWebsite = dr["TookFrom"].ToString() == "1",
                                   IsMelutash = dr["IsMelutash"].ToString() == "1",
                                   TimeOrdered = DateTime.Parse(dr["DateTime1"].ToString()),
                                                QueueNum = Convert.ToInt32(dr["QueueNum"]),
                                                SMS = dr["SMSCode"].ToString()
                                            ;
                       
                       users.Add(user);
                   
               
               catch (Exception e)
               
                   throw e;
               
               finally
               

                   if (dr != null)
                   
                       dr.Close();
                       dr.Dispose();
                   


               
               return users;
           
        

什么给了?

【问题讨论】:

Return DataReader from DataLayer in Using statement的可能重复 【参考方案1】:

让我们试着改进一下这段代码:

private IEnumerable<BursaUser> GetUsers()

    using (var conn = new SqlConnection(SomeConnectionString))
    using (var cmd = conn.CreateCommand())
    
        conn.Open();
        cmd.CommandText = "SELECT WorkerNum, CompanyName, ... FROM Users";
        using (var reader = cmd.ExecuteReader())
        
            while (reader.Read())
            
                var user = new User
                
                    UserId = reader.GetInt32(reader.GetOrdinal("WorkerNum")),
                    CompanyName = reader.GetString(reader.GetOrdinal("CompanyName")),
                    // TODO: complete other fields
                ;
                // TODO: do the tests and complete the complex properties
                yield return user;
            
        
    

现在这段代码是完全可重入和线程安全的。您不需要任何锁定。

【讨论】:

+1,很好的答案。我要添加两件事:我总是明确地Close 我的数据读取器和连接,因为我注意到不这样做会导致在Dispose 期间抛出异常。 -- 其次,我认为让这个方法变得懒惰(通过返回使用yield return 构建的IEnumerable&lt;T&gt;)是一个好主意,但并非在所有情况下都如此。毕竟,只要序列没有被完全消耗,数据库连接就会保持打开状态。 @stakx,嗯,这很奇怪。我从来没有明确地关闭我的数据阅读器,也从来没有遇到过任何问题。 @Darin:直到今天我还没有找到这些问题的确切原因。 IIRC 在我已经使用过另一个阅读器后尝试打开第二个阅读器时,我遇到了这种情况。 ADO.NET 似乎跟踪与事务相关的所有数据读取器;事实上,任何时候都只能有一个。原来是因为我没有明确Close第一个,当我尝试使用第二个时出现异常。 (我可能会在这里弄错一些细节,因为我是从记忆中叙述的。) @Eitan,这很难想象。如果您按照我的说明编写代码,则不会出现此类异常。 好的,我使用了 Darin 的代码,但之后明确关闭了数据读取器,它可以工作,谢谢你们。

以上是关于我不断收到此错误:“阅读器关闭时调用读取无效”的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试输入 phpunit 时,我不断收到此错误

运行此代码时不断收到此错误

我正在尝试使用硒,但不断收到此错误 [重复]

当我启动下面的代码时,我不断收到此错误

我不断收到此错误:找不到“对象”类型的不同支持对象“[对象对象]”。 NgFor 只支持

为啥我不断收到此错误:SQL 命令未正确结束以插入值? [复制]