我一直收到这个错误:“读取器关闭时无效尝试调用Read”

时间:2011-02-06 10:40:05

标签: c# .net multithreading ado.net datareader

这是我的代码,我关闭并打开阅读器,它仍然无法正常工作。一些线程可以同时访问此函数,但存在锁定。它在开始时工作了几次,但迟早我得到了“读取器关闭时无效尝试调用读取”的异常

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;
           }
        }

是什么给出了?

1 个答案:

答案 0 :(得分:11)

让我们尝试稍微改进一下这段代码:

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;
            }
        }
    }
}

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