Static class members disappearing (GC collected?!)

G

Guest

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.
 
G

Guest

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.
 
G

Guest

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 said:
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 said:
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.
 
G

Guest

Vladislav said:
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 said:
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 said:
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.
 
G

Guest

Is there any chance that a request can be handled by more than one thread? Is
this ThreadStatic reliable?

Göran Andersson said:
Vladislav said:
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 said:
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.
 
G

Guest

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 said:
Is there any chance that a request can be handled by more than one thread? Is
this ThreadStatic reliable?

Göran Andersson said:
Vladislav said:
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.

:

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.
 
G

Guest

Thanks a lot!

Göran Andersson said:
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 said:
Is there any chance that a request can be handled by more than one thread? Is
this ThreadStatic reliable?

Göran Andersson said:
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.

:

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top