programing

생성자 직후에 NullReferenceException 오류가 발생한 이유는 무엇입니까?

yellowcard 2023. 6. 19. 21:22
반응형

생성자 직후에 NullReferenceException 오류가 발생한 이유는 무엇입니까?

저는 몇 주 동안 인트라넷에서 asp.net 웹사이트를 실시간으로 운영해 왔습니다.방금 application_error emailer 메서드에서 처리되지 않은 예외가 있는 이메일을 받았습니다.

여기 있습니다(더 잘 표시되도록 일부 경로를 정리했습니다).

예외 : 개체 참조가 개체의 인스턴스로 설정되지 않았습니다.시스템에 추적 스택:.컬렉션.포괄적인.사전 2.시스템에 삽입(키 키, TV 값, 부울 추가).컬렉션.포괄적인.사전 2.TimesheetDomain에서 추가(TKey 키, TV 값).데이터 매퍼.직원 구성원 데이터.TimesheetDomain\DataMappers\StaffMemberData.cs:line 362의 ReadStaff(SqlDataReader Reader)

TimesheetDomain에 있습니다.데이터 매퍼.직원 구성원 데이터.TimesheetDomain\DataMappers\StaffMemberData.cs:line 401의 GetStaffMember(문자열 이름)

TimesheetDomain에 있습니다.서비스 계층.타임시트 관리자.TimesheetDomain\의 GetUserFromName(문자열 이름)서비스 계층\TimesheetManager.cs:line 199

사용자 확인에서.WebTimesheets의 \App_Code\UserVerification.cs:line 29에서 GetCurrentUser().\WebTimesheets\WebTimesheets.master.cs:line 의 OnInit(이벤트 인수) 159

시스템에서.웹.UI.컨트롤.시스템에서 InitRecursive(컨테이너 이름 지정 제어)를 선택합니다.웹.UI.컨트롤.시스템에서 InitRecursive(컨테이너 이름 지정 제어)를 선택합니다.웹.UI.페이지.ProcessRequestMain(부울에는 AsyncPoint 이전 단계 포함, 부울에는 AsyncPoint 이후 단계 포함)

기본적으로 데이터 리더를 읽어 직원 구성원 개체를 만드는 ReadStaff 메서드에서 오류가 발생한 것 같습니다.다음은 코드 부분입니다.

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을 제거하면 .NullReferenceException발생합니다.

나는 도대체 어떻게 된 일인지 보려고 애쓰고 있습니다.newMember마지막 세 번째 줄(오류된 줄)에서 null입니다.

는 Resharper/VS일 수 null왜냐하면 제가 선택한 세 개의 시공자가 있기 때문입니다.

이 오류를 해결하기 위해 제가 어디를 찾을 수 있는지 누가 제안해 줄 수 있습니까?이는 단 한 번 발생했으며 사이트가 활성화된 이후로 수천 번의 호출이 있었습니다.

감사해요.

[EDIT] 요청하신 대로, 여기 직원의 I 비교기가 있습니다.

/// <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");
    }
}

그리고 그것은 IC와 유사한 구현에 사용됩니다.

/// <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를 사용할 수 있으므로 여러 스레드에서 동일한 사전을 동시에 조작하는 것과 관련된 스레드화 문제를 방지할 수 있습니다.

이는 단 한 번 발생했으며 사이트가 활성화된 이후로 수천 번의 호출이 있었습니다.

이것을 읽은 후에, 저는 .NET이 메모리를 다 써버려서 더 이상 Dictionary 키를 만들지 못했을 수도 있다는 결론을 내릴 수 있습니다. 그것은 실제로 당신의 잘못이 아닐 수도 있습니다.그러나 세션/응용프로그램 변수에 너무 많은 정보를 저장하려고 시도하여 웹 응용프로그램의 메모리 설치 공간을 늘렸을 때 이러한 오류가 발생했습니다.하지만 우리는 사전이나 목록에 10,000개의 항목을 저장하는 것과 같은 우리의 숫자가 매우 높아졌을 때 그러한 오류를 얻었습니다.

패턴은 좋지만, 관계형 형식으로 정보를 저장하기 위해 데이터베이스를 사용한다는 것도 알아야 합니다. 메모리를 사용하여 유사한 것을 저장하기 시작하면 강력한 데이터베이스를 무시하는 것입니다.데이터베이스는 값을 캐시할 수도 있습니다.

어리석게 들릴 수도 있지만 24시간마다 윈도우 서버가 다시 시작됩니다. 트래픽이 없는 자정에 말입니다.그것은 우리가 그러한 오류를 제거하는 데 도움이 되었습니다.모든 캐시/로그를 삭제하기 위해 일정에 따라 정기적으로 서버를 재시작합니다.

눈에 띄는 게 하나도 안 보여요.SQL을 실행하여 데이터베이스에 잘못된 데이터가 있는지 확인합니다.문제는 관련 입력 양식의 이상 버그일 수 있습니다.지금까지 코드가 수천 번 이상 문제 없이 실행된 경우 다음에 발생할 경우 최소한 직원 ID를 얻을 수 있도록 추가 예외 처리/보고를 해당 코드 블록 주위에 감쌀 것입니다.

이런 일로 많은 시간을 허비할 수도 있습니다.가장 편리한 접근 방식은 위/제어된 조건에서 다시 고장이 발생하도록 하는 것일 수 있습니다. 문제가 발생하는 수준이 허용 가능/관리 가능/소량이라고 가정할 때입니다.

즉각적인 필요성을 충족시키지는 못하겠지만, 특히 낮은 실패율로 문제를 해결하는 가장 좋은 방법일 수도 있습니다.

다른 사람들이 말했듯이, 비교가 문제를 일으킬 수 있습니다.
비교 기준에 null 값이 포함되어 있습니까?구체적으로 문자열 속성?

예를 들어, 이름이나 성 또는 emailId가 null인 경우 비교를 위해 사전 내에서 사용할 때 오류가 발생할 수 있습니다.

편집: 관리자 및 직원 구성원 및 관리자 직원 클래스는 어떻게 관련되어 있습니까?
코드에서 두 인스턴스를 모두 StaffMember에 캐스팅합니다.Supervisor와 Staff Member 클래스가 관련이 없다면 문제가 될 수도 있을 것 같습니다.

EDIT2: 사전 인스턴스의 스크립트는 무엇입니까?애플리케이션 레벨/세션 레벨에서 공유됩니까?여러 스레드에서 읽기/쓰기를 시도할 수 있습니까?

스레드화와 관련이 없는 이 예외를 본 또 다른 방법은 사전을 직렬화할 때입니다.이 경우에는 비어 있었지만 역직렬화된 인스턴스의 Insert() 메서드에서 NullReferenceException을 받았습니다.

제 경우 단순한 변경 사항은 역직렬화 후 새 인스턴스를 생성하는 것입니다.직렬화로 인해 사전이 손상된 것인지 아니면 사전이 정의된 유형인지 알 수 없습니다.

제 경우에는 (그리고 제가 이것들을 제공한) 직렬화 대리자 없이는 유형을 직렬화할 수 없습니다. 하지만 사전에 문제가 있을 수 있습니다.그러나 다시, 사전은 비어 있었고 이것은 여전히 발생했습니다.

언급URL : https://stackoverflow.com/questions/1320264/how-did-i-get-this-nullreferenceexception-error-here-right-after-the-constructor

반응형