Static class members disappearing (GC collected?!)

Discussion in 'ASP .Net' started by =?Utf-8?B?VmxhZGlzbGF2IEtvc2V2?=, May 15, 2006.

  1. I have this strange problem now twice: I am writing this relatevely large web
    site on 2.0 and I made a static class, which I use for url encoding and
    deconding (for remapping purposes). This static class needs the session
    context to encode a url (because I stored the current language there), so I
    made a static field of type HttpContext, which I refresh every reqest by
    assigning the current context.

    Now, every now and then I get this runtime error that the Session property
    is not set (Object reference not set to instance of an object) and it's
    completely random.

    I suspect that it has something to do with the fact that the class is static
    and GC, but I can't really figure this out.

    I had the same problem in 1.1 a while ago with the same site when I wanted
    to make the SqlConnection a static property and connect on Application_Start
    and disconnect on Application_End. Every n-th request the SqlConnection
    disappeared.

    Any suggestions?

    I pretty much would like to know why this things happen.
     
    =?Utf-8?B?VmxhZGlzbGF2IEtvc2V2?=, May 15, 2006
    #1
    1. Advertising

  2. The reason is that all requests share the same static variable. Imagine
    this scenario:

    Request 1 arrives and thread 1 is started to handle it
    Thread 1 stores it's context in the static variable
    Thread 1 starts working
    Request 2 arrives and thread 2 is started to handle it
    Thread 2 stores it's context in the static variable
    Thread 2 starts working
    Thread 1 continues working
    Thread 2 uses the static varible - this works fine
    Thread 1 uses the static variable - and gets the wrong context
    Thread 2 finishes
    Thread 2 sends a response to the browser
    The context of thread 2 is disposed
    Thread 1 tries to use the static variable - and dies

    Here you see two problems. The static variable contains the context of
    the last request to arrive. That means that some threads will get the
    wrong context, and if the last request is first to finish, the static
    variable will reference a context that is disposed and no longer has a
    reference to a session object.

    The solution is to use one instance of the variable for each thread.
    This can be done in two ways:

    1. Don't use a static class. Create one instance of the class for each page.

    2. Use the [ThreadStatic] attribute to create an instance of the static
    variable for each thread.

    One thing you should be aware of if you choose to use a ThreadStatic
    variables, is that the static constructor of the class is only run when
    the class is loaded, not for every thread. If you have this code:

    [ThreadStatic] static int answer = 42;

    The code that initializes the variable is actually placed in the static
    constructor. That means that the first thread that uses the class will
    get the value 42, but for every thread after that, the value will be zero.


    Vladislav Kosev wrote:
    > I have this strange problem now twice: I am writing this relatevely large web
    > site on 2.0 and I made a static class, which I use for url encoding and
    > deconding (for remapping purposes). This static class needs the session
    > context to encode a url (because I stored the current language there), so I
    > made a static field of type HttpContext, which I refresh every reqest by
    > assigning the current context.
    >
    > Now, every now and then I get this runtime error that the Session property
    > is not set (Object reference not set to instance of an object) and it's
    > completely random.
    >
    > I suspect that it has something to do with the fact that the class is static
    > and GC, but I can't really figure this out.
    >
    > I had the same problem in 1.1 a while ago with the same site when I wanted
    > to make the SqlConnection a static property and connect on Application_Start
    > and disconnect on Application_End. Every n-th request the SqlConnection
    > disappeared.
    >
    > Any suggestions?
    >
    > I pretty much would like to know why this things happen.
    >
     
    =?UTF-8?B?R8O2cmFuIEFuZGVyc3Nvbg==?=, May 15, 2006
    #2
    1. Advertising

  3. Göran, thank you for the excellent response and explanation! I didn't think
    of that a static variable is used in several requests at one time. With this
    in mind, it is obviously a suicide to use a static variable, it will most
    certainly crash, that explains the randomness of the errors.

    On thing that I think is very interesting is that [ThreadStatic] attribute,
    I will certainly read everything there is about it.

    But is it certain that 1 request is 1 thread and visa versa?

    Because if it is not, this will not work as expected. Actually all I need is
    request and/or session level storage, but without using the
    HttpContext.Current in my Business Logic tier, because that makes it unusable
    in every other context.

    "Göran Andersson" wrote:

    > The reason is that all requests share the same static variable. Imagine
    > this scenario:
    >
    > Request 1 arrives and thread 1 is started to handle it
    > Thread 1 stores it's context in the static variable
    > Thread 1 starts working
    > Request 2 arrives and thread 2 is started to handle it
    > Thread 2 stores it's context in the static variable
    > Thread 2 starts working
    > Thread 1 continues working
    > Thread 2 uses the static varible - this works fine
    > Thread 1 uses the static variable - and gets the wrong context
    > Thread 2 finishes
    > Thread 2 sends a response to the browser
    > The context of thread 2 is disposed
    > Thread 1 tries to use the static variable - and dies
    >
    > Here you see two problems. The static variable contains the context of
    > the last request to arrive. That means that some threads will get the
    > wrong context, and if the last request is first to finish, the static
    > variable will reference a context that is disposed and no longer has a
    > reference to a session object.
    >
    > The solution is to use one instance of the variable for each thread.
    > This can be done in two ways:
    >
    > 1. Don't use a static class. Create one instance of the class for each page.
    >
    > 2. Use the [ThreadStatic] attribute to create an instance of the static
    > variable for each thread.
    >
    > One thing you should be aware of if you choose to use a ThreadStatic
    > variables, is that the static constructor of the class is only run when
    > the class is loaded, not for every thread. If you have this code:
    >
    > [ThreadStatic] static int answer = 42;
    >
    > The code that initializes the variable is actually placed in the static
    > constructor. That means that the first thread that uses the class will
    > get the value 42, but for every thread after that, the value will be zero.
    >
    >
    > Vladislav Kosev wrote:
    > > I have this strange problem now twice: I am writing this relatevely large web
    > > site on 2.0 and I made a static class, which I use for url encoding and
    > > deconding (for remapping purposes). This static class needs the session
    > > context to encode a url (because I stored the current language there), so I
    > > made a static field of type HttpContext, which I refresh every reqest by
    > > assigning the current context.
    > >
    > > Now, every now and then I get this runtime error that the Session property
    > > is not set (Object reference not set to instance of an object) and it's
    > > completely random.
    > >
    > > I suspect that it has something to do with the fact that the class is static
    > > and GC, but I can't really figure this out.
    > >
    > > I had the same problem in 1.1 a while ago with the same site when I wanted
    > > to make the SqlConnection a static property and connect on Application_Start
    > > and disconnect on Application_End. Every n-th request the SqlConnection
    > > disappeared.
    > >
    > > Any suggestions?
    > >
    > > I pretty much would like to know why this things happen.
    > >

    >
     
    =?Utf-8?B?VmxhZGlzbGF2IEtvc2V2?=, May 15, 2006
    #3
  4. Vladislav Kosev wrote:
    > Göran, thank you for the excellent response and explanation! I didn't think
    > of that a static variable is used in several requests at one time. With this
    > in mind, it is obviously a suicide to use a static variable, it will most
    > certainly crash, that explains the randomness of the errors.
    >
    > On thing that I think is very interesting is that [ThreadStatic] attribute,
    > I will certainly read everything there is about it.
    >
    > But is it certain that 1 request is 1 thread and visa versa?


    Yes. Every request is handled in a separate thread.

    > Because if it is not, this will not work as expected. Actually all I need is
    > request and/or session level storage, but without using the
    > HttpContext.Current in my Business Logic tier, because that makes it unusable
    > in every other context.
    >
    > "Göran Andersson" wrote:
    >
    >> The reason is that all requests share the same static variable. Imagine
    >> this scenario:
    >>
    >> Request 1 arrives and thread 1 is started to handle it
    >> Thread 1 stores it's context in the static variable
    >> Thread 1 starts working
    >> Request 2 arrives and thread 2 is started to handle it
    >> Thread 2 stores it's context in the static variable
    >> Thread 2 starts working
    >> Thread 1 continues working
    >> Thread 2 uses the static varible - this works fine
    >> Thread 1 uses the static variable - and gets the wrong context
    >> Thread 2 finishes
    >> Thread 2 sends a response to the browser
    >> The context of thread 2 is disposed
    >> Thread 1 tries to use the static variable - and dies
    >>
    >> Here you see two problems. The static variable contains the context of
    >> the last request to arrive. That means that some threads will get the
    >> wrong context, and if the last request is first to finish, the static
    >> variable will reference a context that is disposed and no longer has a
    >> reference to a session object.
    >>
    >> The solution is to use one instance of the variable for each thread.
    >> This can be done in two ways:
    >>
    >> 1. Don't use a static class. Create one instance of the class for each page.
    >>
    >> 2. Use the [ThreadStatic] attribute to create an instance of the static
    >> variable for each thread.
    >>
    >> One thing you should be aware of if you choose to use a ThreadStatic
    >> variables, is that the static constructor of the class is only run when
    >> the class is loaded, not for every thread. If you have this code:
    >>
    >> [ThreadStatic] static int answer = 42;
    >>
    >> The code that initializes the variable is actually placed in the static
    >> constructor. That means that the first thread that uses the class will
    >> get the value 42, but for every thread after that, the value will be zero.
    >>
    >>
    >> Vladislav Kosev wrote:
    >>> I have this strange problem now twice: I am writing this relatevely large web
    >>> site on 2.0 and I made a static class, which I use for url encoding and
    >>> deconding (for remapping purposes). This static class needs the session
    >>> context to encode a url (because I stored the current language there), so I
    >>> made a static field of type HttpContext, which I refresh every reqest by
    >>> assigning the current context.
    >>>
    >>> Now, every now and then I get this runtime error that the Session property
    >>> is not set (Object reference not set to instance of an object) and it's
    >>> completely random.
    >>>
    >>> I suspect that it has something to do with the fact that the class is static
    >>> and GC, but I can't really figure this out.
    >>>
    >>> I had the same problem in 1.1 a while ago with the same site when I wanted
    >>> to make the SqlConnection a static property and connect on Application_Start
    >>> and disconnect on Application_End. Every n-th request the SqlConnection
    >>> disappeared.
    >>>
    >>> Any suggestions?
    >>>
    >>> I pretty much would like to know why this things happen.
    >>>
     
    =?UTF-8?B?R8O2cmFuIEFuZGVyc3Nvbg==?=, May 15, 2006
    #4
  5. Is there any chance that a request can be handled by more than one thread? Is
    this ThreadStatic reliable?

    "Göran Andersson" wrote:

    > Vladislav Kosev wrote:
    > > Göran, thank you for the excellent response and explanation! I didn't think
    > > of that a static variable is used in several requests at one time. With this
    > > in mind, it is obviously a suicide to use a static variable, it will most
    > > certainly crash, that explains the randomness of the errors.
    > >
    > > On thing that I think is very interesting is that [ThreadStatic] attribute,
    > > I will certainly read everything there is about it.
    > >
    > > But is it certain that 1 request is 1 thread and visa versa?

    >
    > Yes. Every request is handled in a separate thread.
    >
    > > Because if it is not, this will not work as expected. Actually all I need is
    > > request and/or session level storage, but without using the
    > > HttpContext.Current in my Business Logic tier, because that makes it unusable
    > > in every other context.
    > >
    > > "Göran Andersson" wrote:
    > >
    > >> The reason is that all requests share the same static variable. Imagine
    > >> this scenario:
    > >>
    > >> Request 1 arrives and thread 1 is started to handle it
    > >> Thread 1 stores it's context in the static variable
    > >> Thread 1 starts working
    > >> Request 2 arrives and thread 2 is started to handle it
    > >> Thread 2 stores it's context in the static variable
    > >> Thread 2 starts working
    > >> Thread 1 continues working
    > >> Thread 2 uses the static varible - this works fine
    > >> Thread 1 uses the static variable - and gets the wrong context
    > >> Thread 2 finishes
    > >> Thread 2 sends a response to the browser
    > >> The context of thread 2 is disposed
    > >> Thread 1 tries to use the static variable - and dies
    > >>
    > >> Here you see two problems. The static variable contains the context of
    > >> the last request to arrive. That means that some threads will get the
    > >> wrong context, and if the last request is first to finish, the static
    > >> variable will reference a context that is disposed and no longer has a
    > >> reference to a session object.
    > >>
    > >> The solution is to use one instance of the variable for each thread.
    > >> This can be done in two ways:
    > >>
    > >> 1. Don't use a static class. Create one instance of the class for each page.
    > >>
    > >> 2. Use the [ThreadStatic] attribute to create an instance of the static
    > >> variable for each thread.
    > >>
    > >> One thing you should be aware of if you choose to use a ThreadStatic
    > >> variables, is that the static constructor of the class is only run when
    > >> the class is loaded, not for every thread. If you have this code:
    > >>
    > >> [ThreadStatic] static int answer = 42;
    > >>
    > >> The code that initializes the variable is actually placed in the static
    > >> constructor. That means that the first thread that uses the class will
    > >> get the value 42, but for every thread after that, the value will be zero.
    > >>
    > >>
    > >> Vladislav Kosev wrote:
    > >>> I have this strange problem now twice: I am writing this relatevely large web
    > >>> site on 2.0 and I made a static class, which I use for url encoding and
    > >>> deconding (for remapping purposes). This static class needs the session
    > >>> context to encode a url (because I stored the current language there), so I
    > >>> made a static field of type HttpContext, which I refresh every reqest by
    > >>> assigning the current context.
    > >>>
    > >>> Now, every now and then I get this runtime error that the Session property
    > >>> is not set (Object reference not set to instance of an object) and it's
    > >>> completely random.
    > >>>
    > >>> I suspect that it has something to do with the fact that the class is static
    > >>> and GC, but I can't really figure this out.
    > >>>
    > >>> I had the same problem in 1.1 a while ago with the same site when I wanted
    > >>> to make the SqlConnection a static property and connect on Application_Start
    > >>> and disconnect on Application_End. Every n-th request the SqlConnection
    > >>> disappeared.
    > >>>
    > >>> Any suggestions?
    > >>>
    > >>> I pretty much would like to know why this things happen.
    > >>>

    >
     
    =?Utf-8?B?VmxhZGlzbGF2IEtvc2V2?=, May 15, 2006
    #5
  6. IIS uses one thread to handle a request. If it started more than one
    thread to handle a request, that would mean that there would be more
    than one response, and that of course wouldn't work.

    You can start new threads from your code, but then you have to take
    responsibility for those.

    Vladislav Kosev wrote:
    > Is there any chance that a request can be handled by more than one thread? Is
    > this ThreadStatic reliable?
    >
    > "Göran Andersson" wrote:
    >
    >> Vladislav Kosev wrote:
    >>> Göran, thank you for the excellent response and explanation! I didn't think
    >>> of that a static variable is used in several requests at one time. With this
    >>> in mind, it is obviously a suicide to use a static variable, it will most
    >>> certainly crash, that explains the randomness of the errors.
    >>>
    >>> On thing that I think is very interesting is that [ThreadStatic] attribute,
    >>> I will certainly read everything there is about it.
    >>>
    >>> But is it certain that 1 request is 1 thread and visa versa?

    >> Yes. Every request is handled in a separate thread.
    >>
    >>> Because if it is not, this will not work as expected. Actually all I need is
    >>> request and/or session level storage, but without using the
    >>> HttpContext.Current in my Business Logic tier, because that makes it unusable
    >>> in every other context.
    >>>
    >>> "Göran Andersson" wrote:
    >>>
    >>>> The reason is that all requests share the same static variable. Imagine
    >>>> this scenario:
    >>>>
    >>>> Request 1 arrives and thread 1 is started to handle it
    >>>> Thread 1 stores it's context in the static variable
    >>>> Thread 1 starts working
    >>>> Request 2 arrives and thread 2 is started to handle it
    >>>> Thread 2 stores it's context in the static variable
    >>>> Thread 2 starts working
    >>>> Thread 1 continues working
    >>>> Thread 2 uses the static varible - this works fine
    >>>> Thread 1 uses the static variable - and gets the wrong context
    >>>> Thread 2 finishes
    >>>> Thread 2 sends a response to the browser
    >>>> The context of thread 2 is disposed
    >>>> Thread 1 tries to use the static variable - and dies
    >>>>
    >>>> Here you see two problems. The static variable contains the context of
    >>>> the last request to arrive. That means that some threads will get the
    >>>> wrong context, and if the last request is first to finish, the static
    >>>> variable will reference a context that is disposed and no longer has a
    >>>> reference to a session object.
    >>>>
    >>>> The solution is to use one instance of the variable for each thread.
    >>>> This can be done in two ways:
    >>>>
    >>>> 1. Don't use a static class. Create one instance of the class for each page.
    >>>>
    >>>> 2. Use the [ThreadStatic] attribute to create an instance of the static
    >>>> variable for each thread.
    >>>>
    >>>> One thing you should be aware of if you choose to use a ThreadStatic
    >>>> variables, is that the static constructor of the class is only run when
    >>>> the class is loaded, not for every thread. If you have this code:
    >>>>
    >>>> [ThreadStatic] static int answer = 42;
    >>>>
    >>>> The code that initializes the variable is actually placed in the static
    >>>> constructor. That means that the first thread that uses the class will
    >>>> get the value 42, but for every thread after that, the value will be zero.
    >>>>
    >>>>
    >>>> Vladislav Kosev wrote:
    >>>>> I have this strange problem now twice: I am writing this relatevely large web
    >>>>> site on 2.0 and I made a static class, which I use for url encoding and
    >>>>> deconding (for remapping purposes). This static class needs the session
    >>>>> context to encode a url (because I stored the current language there), so I
    >>>>> made a static field of type HttpContext, which I refresh every reqest by
    >>>>> assigning the current context.
    >>>>>
    >>>>> Now, every now and then I get this runtime error that the Session property
    >>>>> is not set (Object reference not set to instance of an object) and it's
    >>>>> completely random.
    >>>>>
    >>>>> I suspect that it has something to do with the fact that the class is static
    >>>>> and GC, but I can't really figure this out.
    >>>>>
    >>>>> I had the same problem in 1.1 a while ago with the same site when I wanted
    >>>>> to make the SqlConnection a static property and connect on Application_Start
    >>>>> and disconnect on Application_End. Every n-th request the SqlConnection
    >>>>> disappeared.
    >>>>>
    >>>>> Any suggestions?
    >>>>>
    >>>>> I pretty much would like to know why this things happen.
    >>>>>
     
    =?UTF-8?B?R8O2cmFuIEFuZGVyc3Nvbg==?=, May 15, 2006
    #6
  7. Thanks a lot!

    "Göran Andersson" wrote:

    > IIS uses one thread to handle a request. If it started more than one
    > thread to handle a request, that would mean that there would be more
    > than one response, and that of course wouldn't work.
    >
    > You can start new threads from your code, but then you have to take
    > responsibility for those.
    >
    > Vladislav Kosev wrote:
    > > Is there any chance that a request can be handled by more than one thread? Is
    > > this ThreadStatic reliable?
    > >
    > > "Göran Andersson" wrote:
    > >
    > >> Vladislav Kosev wrote:
    > >>> Göran, thank you for the excellent response and explanation! I didn't think
    > >>> of that a static variable is used in several requests at one time. With this
    > >>> in mind, it is obviously a suicide to use a static variable, it will most
    > >>> certainly crash, that explains the randomness of the errors.
    > >>>
    > >>> On thing that I think is very interesting is that [ThreadStatic] attribute,
    > >>> I will certainly read everything there is about it.
    > >>>
    > >>> But is it certain that 1 request is 1 thread and visa versa?
    > >> Yes. Every request is handled in a separate thread.
    > >>
    > >>> Because if it is not, this will not work as expected. Actually all I need is
    > >>> request and/or session level storage, but without using the
    > >>> HttpContext.Current in my Business Logic tier, because that makes it unusable
    > >>> in every other context.
    > >>>
    > >>> "Göran Andersson" wrote:
    > >>>
    > >>>> The reason is that all requests share the same static variable. Imagine
    > >>>> this scenario:
    > >>>>
    > >>>> Request 1 arrives and thread 1 is started to handle it
    > >>>> Thread 1 stores it's context in the static variable
    > >>>> Thread 1 starts working
    > >>>> Request 2 arrives and thread 2 is started to handle it
    > >>>> Thread 2 stores it's context in the static variable
    > >>>> Thread 2 starts working
    > >>>> Thread 1 continues working
    > >>>> Thread 2 uses the static varible - this works fine
    > >>>> Thread 1 uses the static variable - and gets the wrong context
    > >>>> Thread 2 finishes
    > >>>> Thread 2 sends a response to the browser
    > >>>> The context of thread 2 is disposed
    > >>>> Thread 1 tries to use the static variable - and dies
    > >>>>
    > >>>> Here you see two problems. The static variable contains the context of
    > >>>> the last request to arrive. That means that some threads will get the
    > >>>> wrong context, and if the last request is first to finish, the static
    > >>>> variable will reference a context that is disposed and no longer has a
    > >>>> reference to a session object.
    > >>>>
    > >>>> The solution is to use one instance of the variable for each thread.
    > >>>> This can be done in two ways:
    > >>>>
    > >>>> 1. Don't use a static class. Create one instance of the class for each page.
    > >>>>
    > >>>> 2. Use the [ThreadStatic] attribute to create an instance of the static
    > >>>> variable for each thread.
    > >>>>
    > >>>> One thing you should be aware of if you choose to use a ThreadStatic
    > >>>> variables, is that the static constructor of the class is only run when
    > >>>> the class is loaded, not for every thread. If you have this code:
    > >>>>
    > >>>> [ThreadStatic] static int answer = 42;
    > >>>>
    > >>>> The code that initializes the variable is actually placed in the static
    > >>>> constructor. That means that the first thread that uses the class will
    > >>>> get the value 42, but for every thread after that, the value will be zero.
    > >>>>
    > >>>>
    > >>>> Vladislav Kosev wrote:
    > >>>>> I have this strange problem now twice: I am writing this relatevely large web
    > >>>>> site on 2.0 and I made a static class, which I use for url encoding and
    > >>>>> deconding (for remapping purposes). This static class needs the session
    > >>>>> context to encode a url (because I stored the current language there), so I
    > >>>>> made a static field of type HttpContext, which I refresh every reqest by
    > >>>>> assigning the current context.
    > >>>>>
    > >>>>> Now, every now and then I get this runtime error that the Session property
    > >>>>> is not set (Object reference not set to instance of an object) and it's
    > >>>>> completely random.
    > >>>>>
    > >>>>> I suspect that it has something to do with the fact that the class is static
    > >>>>> and GC, but I can't really figure this out.
    > >>>>>
    > >>>>> I had the same problem in 1.1 a while ago with the same site when I wanted
    > >>>>> to make the SqlConnection a static property and connect on Application_Start
    > >>>>> and disconnect on Application_End. Every n-th request the SqlConnection
    > >>>>> disappeared.
    > >>>>>
    > >>>>> Any suggestions?
    > >>>>>
    > >>>>> I pretty much would like to know why this things happen.
    > >>>>>

    >
     
    =?Utf-8?B?VmxhZGlzbGF2IEtvc2V2?=, May 16, 2006
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?Sg==?=

    When are static members garbage collected?

    =?Utf-8?B?Sg==?=, Feb 25, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    356
    bruce barker
    Feb 25, 2004
  2. SaravanaKumar
    Replies:
    6
    Views:
    9,525
    Tony Morris
    Oct 19, 2004
  3. JFCM
    Replies:
    4
    Views:
    5,788
  4. CoolPint
    Replies:
    8
    Views:
    1,033
    Jeff Schwab
    Dec 14, 2003
  5. Hicham Mouline
    Replies:
    5
    Views:
    2,461
    James Kanze
    Dec 19, 2008
Loading...

Share This Page