我是如何在构造函数之后立即得到这个NullReferenceException错误的?

我已经有一个asp.net网站在我们的内联网上运行了几个星期了。 我刚收到来自我的application_error电子邮件方法的电子邮件,发现未处理的exception。

这里清理了一些path,使其更好地显示出来。

exception:对象引用未设置为对象的实例。 堆栈跟踪:在System.Collections.Generic.Dictionary 2.Insert(TKey key, TValue value, Boolean add) at System.Collections.Generic.Dictionary 2.Add(TKey键,TValue值)在TimesheetDomain.DataMappers.StaffMemberData.ReadStaff (SqlDataReader阅读器)在TimesheetDomain \ DataMappers \ StaffMemberData.cs:行362

在TimesheetDomain \ DataMappers \ StaffMemberData.cs中的TimesheetDomain.DataMappers.StaffMemberData.GetStaffMember(String name):行401

在TimesheetDomain \ ServiceLayer \ TimesheetManager.cs中的TimesheetDomain.ServiceLayer.TimesheetManager.GetUserFromName(String name):line 199

位于\ App_Code \ UserVerification.cs中的UserVerification.GetCurrentUser():位于\ WebTimesheets \ WebTimesheets.master.cs中的WebTimesheets.OnInit(EventArgs e)的第29行:第159行

在System.Web.UI.Page.ProcessRequestMain的System.Web.UI.Control.InitRecursive(Control namingContainer)处的System.Web.UI.Control.InitRecursive(Control namingContainer)(布尔值为includeStagesBeforeAsyncPoint,布尔值为includeStagesAfterAsyncPoint)

基本上,它看起来像在我的ReadStaff方法读取数据读取器build立工作人员对象的错误。 这是一些代码:

  while (reader != null && reader.Read()) { StaffMember newMember = null; string firstName = reader["FirstName"].ToString(); string lastName = reader["LastName"].ToString(); int staffID = (int)reader["StaffID"]; int employSection = (int)reader["EmploySection"]; StaffType employType = (StaffType)employSection; string emailAddress = reader["EmailInt"].ToString(); int employCode = (int)reader["ibbwid"]; //check if they are an admin staff member if (IsAdminStaff(employType)) { newMember = new AdminOfficer(firstName, lastName, employType, staffID, emailAddress, employCode); } else { //check if they are a supervisor if (IsASupervisor(staffID)) newMember = new Supervisor(firstName, lastName, employType, staffID, emailAddress, employCode); else newMember = new StaffMember(firstName, lastName, employType, staffID, emailAddress, employCode); } //add to identity map if (!_staffMembers.ContainsKey(staffID)) _staffMembers.Add(staffID, newMember); //****THIS IS LINE 362***** else _staffMembers[staffID] = newMember; 

(第362行是第三行)我正在使用一个身份地图(只读模式的动物书,并认为这是一个好主意 – 可能做错了,乐于发表评论),但那不是过度相关, newMember对象在其他地方,所以如果我删除该块nullreference将会发生。

我正努力想看看newMember在第三行最后一行如何(这是错误的行)

resharper / VS不给我一个警告,它可能是空的 – 因为我select的3个构造函数。

任何人都可以build议我在哪里可以尝试修复这个错误? 它只发生过一次,自该网站上线以来,这种方法已被称为上千次。

谢谢

[编辑]根据要求,这里是工作人员的IComparer

  /// <summary> /// Comparer for staff members - compares on name /// </summary> public class StaffMemberComparer : IComparer { public int Compare(object x, object y) { //check they are staff members if (x is StaffMember && y is StaffMember) { //do a simple string comparison on names StaffMember staffX = x as StaffMember; StaffMember staffY = y as StaffMember; return String.Compare(staffX.FirstName, staffY.FirstName); } throw new Exception("This is for comparing Staff Members"); } } 

并用于IComparable的实现

  /// <summary> /// IComparable implementaiton /// </summary> /// <param name="obj">object to compare to</param> /// <returns></returns> public int CompareTo(object obj) { StaffMemberComparer comparer = new StaffMemberComparer(); return comparer.Compare(this, obj); } 

这几乎肯定是一个线程问题 – 看到这个问题和它接受的答案 。

如果字典实例在插入操作期间从另一个线程被修改,则Dictionary<>.Insert()将在内部抛出一个NullReferenceException

从.NET 4.0开始,您可以使用ConcurrentDictionary并避免与从多个线程同时操作相同字典相关的线程问题。

我看不出有什么明显的。 我会运行一些SQL来检查数据库中的任何不良数据。 这个问题可能是一个相关input表单中的怪胎。 如果代码已经被运行了几千次而没有事件发生,那么我会在代码块中包含一些额外的exception处理/报告,这样至less在下一次发生时可以得到一个staffId。

你可以在这样的东西上烧很多时间。 最简便的方法可能就是让它在上述/受控条件下再次失败,假设其引起的中断级别是可接受的/可pipe理的/轻微的。

我明白,不会满足直接需要知道,但它可能是最好的方法来pipe理这个问题,尤其是如此低的故障率。

正如其他人所说,比较可能会导致这个问题。
比较的任何标准是否包含空值? 具体来说,string属性?

即,如果firstname或lastname或emailId为null,并且如果用于比较,则在字典中用于比较时可能会失败。

编辑:主pipe和员工和AdminStaff类如何相关?
在代码中,您将两个实例都转换为StaffMember。 我的猜测是,如果Supervisor和StaffMember类没有关系,这可能是一个问题。

编辑2:什么是字典实例的scrope? 它在应用程序级别/会话级别共享吗? 是否有可能多个线程可以尝试从它读取/写入?

它只发生过一次,自该网站上线以来,这种方法已被称为上千次。

读完这个之后,我可以得出这样的结论:.NET可能已经耗尽了它的内存,并且不能创build更多的Dictionary键,它可能并不是真正在你的错误的任何地方。 但是,当我们尝试在会话/应用程序variables中存储太多信息,从而增加了Web应用程序的内存占用量时,我们确实遇到了这类错误。 但是当我们的数字变得非常高时,我们得到了这样的错误,比如在Dictionary或者List中存储了10,000个条目。

模式是好的,但你也必须意识到,我们使用数据库来存储关系格式的信息,如果我们开始使用内存来存储类似的东西,那么我们忽略了强大的数据库。 数据库也可以caching你的值。

这可能听起来很愚蠢,但我们有我们的Windows服务器每24小时重新启动,在没有stream量的午夜。 这确实帮助我们摆脱了这样的错误。 我们定期重新启动服务器,以便清除所有caching/日志。

另一种我看到这个与线程无关的exception是序列化字典的时候。 在这种情况下,它是空的,但是在反序列化实例的Insert()方法中仍然有NullReferenceException。

在我的情况下,简单的改变只是在反序列化之后创build一个新的实例。 我不确定序列化是否会破坏词典,或者它是为词典定义的types。

在我的情况下,types不是序列化没有序列化代理(我提供了这些),但也许在字典中的东西有一个问题在这里。 尽pipe如此,字典是空的,这仍然发生。