[c#] ASP.NET 정적 변수의 수명

페이지 클래스 (Global.asax가 아님)에 정의 된 정적 변수에 몇 가지 정보가 있습니다. 다음과 같은 코드에서만 변수를 선언합니다.

protected static int SomeGlobalUnsecureID;
protected static string SomeGlobalUnsecureString;

PageLoad 이벤트에서 변수를 정의합니다. 예를 들어 데이터베이스에서 ID를 확인하고 SomeGlobalUnsecureID와 다른 경우 SomeGlobalUnsecureID 및 String을 다른 곳에서 업데이트하고 그렇지 않으면 그대로 둡니다. 이것은 내 앱에서 완벽하게 안전합니다. 논리 (즉, 이러한 데이터는 안전하지 않고 누구나 액세스 할 수 있으며 문제 없음) 내가 성취하고 싶은 유일한 것은

  1. 연결된 사용자에 관계없이 동일한 양의 메모리를 보유

  2. 영구 정보가 ‘메모리’의 정보와 다른 경우에만 변경하십시오 (실제로 문자열을 읽는 데 시간이 많이 걸리기 때문입니다.

이제 PageLoad에서 확인 했으므로 다시로드 된 페이지에서 문제가 없습니다. 그러나 내 페이지는 WebMethods로 가득 차 있으며 때로는 정적 변수가 0으로 표시되는 것을 볼 수 있습니다. 그리고 이상한 부분은 다음과 같습니다. 정적 변수가 0이 되어도 세션은 여전히 ​​활성 상태입니다 (따라서 서버 또는 앱 풀 재시작 없음 등).

이것은 나에게 정말 이상합니다. 정적 변수는 응용 프로그램이 종료 될 때까지 값을 유지한다고 가정합니다. 그러나 세션이 만료되지 않았더라도 정적 변수는 0이됩니다. 당신은 무엇을 제안합니까? 응용 프로그램 변수를 사용하는 것이 더 나은 선택입니까? 웹에서 읽은 모든 문서는 응용 프로그램 변수 대신 정적 변수를 제안합니다. 어떻게 든 다르게 선언해야합니까?



답변

정적 변수는 앱 도메인의 수명 동안 유지됩니다. 따라서 정적 변수를 ‘재설정’하게 만드는 두 가지 사항은 앱 도메인 다시 시작 또는 새 클래스 사용입니다. aspx 페이지 클래스에 저장된 정적 변수가있는 경우 ASP.NET이 aspx 페이지를 새 클래스로 다시 컴파일하여 이전 페이지 클래스를 새 클래스로 대체하기로 결정하면 정적 변수가 손실 될 수 있습니다.

이러한 이유로 시스템이 클래스를 다시 시작하거나 교체하기로 결정한 경우 ( .NET은 실행중인 앱 도메인에서 클래스 / 어셈블리를 종료하거나 언로드하지 않음 ) 다시 시작 또는 교체를 통해 새 클래스를 가져 오므로 정적 변수가 재설정됩니다. 이것은 App_Code 폴더의 aspx 페이지와 클래스 모두에 적용됩니다.

ASP.NET은 어떤 이유로 든 클래스를 다시 컴파일해야한다고 생각하는 경우 클래스를 대체합니다 ( ASP.NET 동적 컴파일 참조 ).

앱 도메인 다시 시작으로 인한 정적 변수 손실을 방지 할 수는 없지만 클래스 교체에서는이를 방지 할 수 있습니다. aspx 페이지가 아니고 App_Code 디렉터리에없는 클래스에 정적 변수를 넣을 수 있습니다. static class프로그램 의 어딘가에 배치 할 수 있습니다 .

public static class GlobalVariables
{
    public static int SomeGlobalUnsecureID;
    public  static string SomeGlobalUnsecureString;
}

정적 변수는 풀당입니다. 즉, asp.net 사이트를 실행하는 2 개의 풀이있는 경우 2 개의 다른 정적 변수가 있습니다. ( 웹 가든 모드 )

시스템이 이러한 방법 중 하나로 asp.net 응용 프로그램을 다시 시작하면 정적 변수가 손실됩니다.

  1. 풀은 재 컴파일이 필요하다고 결정합니다.
  2. app_offline.htm 파일을 엽니 다.
  3. 풀을 수동으로 다시 시작합니다.
  4. 풀이 정의한 일부 제한에 도달하고 다시 시작합니다.
  5. 어떤 이유로 든 iis 또는 풀을 다시 시작합니다.

이 정적 변수는 스레드로부터 안전하지 않으며 다른 스레드에서 액세스하는 경우 특히 lock 키워드 를 사용해야합니다 .

앱을 다시 시작하면 무슨 일이 있어도 통계가 재설정되므로 실제로 데이터를 유지하려면 사용자 지정 클래스를 사용하여 데이터베이스에 데이터를 저장해야합니다. 당신은에서 사용자 별 정보를 저장할 수 있습니다 세션 상태데이터베이스 세션 상태 모드 . ASP.NET 응용 프로그램 상태 / 변수는 데이터베이스가 아닌 메모리에 저장 되므로 앱 도메인을 다시 시작할 때도 손실되므로 도움이되지 않습니다 .


답변

정적 변수의 수명을 위해 다음 두 가지 사항도 중요하다고 생각합니다.

1-응용 프로그램 풀의 고급 설정에서 “재활용”-> “정기 시간 간격 (분)”설정을 확인합니다. 기본값은 1740입니다. 즉, 애플리케이션 풀 재활용으로 인해 29 시간마다 정적 변수가 손실됩니다. 이 설정은 가능한 메모리 누수를 종료하는 데 사용됩니다. 이 설정은 변경하지 않겠습니다 ..

2-응용 프로그램 풀의 고급 설정에서 “프로세스 모델”-> “유휴 시간 제한 (분)”설정을 확인합니다. 기본값은 20입니다. 즉, 애플리케이션 풀에서 20 분 동안 비활성 상태 일 때마다 작업자 프로세스가 종료 / 일시 중단되어 정적 변수가 손실됩니다. 이 설정은 응용 프로그램 풀이 일정 시간 동안 사용되지 않을 때 리소스를 확보하는 데 사용됩니다. 0으로 설정하여 시간 초과를 비활성화 할 수 있습니다.


답변

정적 변수는 모든 객체를 동일한 값으로 저장하는 데 사용됩니다.

protected void Page_Load(object sender, EventArgs e)
{
    sss s1, s2;
    s1 = new sss();
    s1.TotalMark = 10;
    s2 = new sss();
    s2.TotalMark = 20;
    sss.SchoolName = "St.Joseph's Hr.Sec.S"; //We can access through class and assign common to all
    s1.PrintData();
    s2.PrintData();
}

public class sss
{
    public static string SchoolName { set; get; }
    public int TotalMark { set; get; }
    public string StudentName{set;get;}
    public void PrintData()
    {
        Console.WriteLine(TotalMark);
        Console.WriteLine(SchoolName);
        Console.WriteLine(StudentName);
    }
}


답변