Article ID: 893666 - View products that this article applies to.
ASP.NET Support Voice column
Troubleshooting ASP.NET applications with the use of static keywordsTo customize this column to your needs, we want to invite you to submit your ideas about topics that interest you and issues that you want to see addressed in future Knowledge Base articles and Support Voice columns. You can submit your ideas and feedback using the Ask For It
(http://support.microsoft.com/common/survey.aspx?scid=sw;en;1176&p0=&p1=&p2=&p3=&p4=)form. There's also a link to the form at the bottom of this column.
Welcome to the Microsoft ASP.NET Support Voice column! My name is Jerry Orman. I have been with Microsoft over 5 years, and have spent most of my time focused on Web-related technologies such as Microsoft FrontPage and the new Microsoft SharePoint technologies. I have spent the last year working with Microsoft ASP.NET as a support engineer. This month in the Support Voice column, I am going to describe troubleshooting ASP.NET applications with the use of static keywords.
StaticsThis article discusses two different behaviors that are caused by static keywords and that can be difficult to troubleshoot. Hopefully after you read this article, you can avoid these behaviors in your applications and be able to better diagnose them if they occur.
Users see incorrect dataOne symptom that is very difficult to troubleshoot occurs when a user submits data, but another user's information is displayed or is entered into a database. This behavior typically occurs because of incorrect use of static variables in classes. A static object is instantiated one time for each application domain, and all processing in the application shares the same object. For example, let's say you set up a static property in a class by using the following code.
The MyData property is static and public. You can access it anywhere in your application by using the following syntax:
So now imagine that you have a page that sets the value of MyData, and then does some work with it. If multiple users hit the page at the same time, you now have a race condition where the last user who updated MyData wins. The following sample shows this behavior by setting the static object during a button_click event. This sample also makes the thread sleep for 15 seconds. This allows both requests to run at the same time. To do this, follow these steps:
Avoid this behaviorThe best way to avoid this behavior is to not make the object static and to use an instance of the class to set and to retrieve the values. The property is no longer shared because a copy of the object is created for each request, and you will not see this behavior. To avoid this behavior, follow these steps:
NullReferenceException caused by staticsAnother behavior that occurs when you use statics is a System.NullReferenceException exception. For example, you change your button_click event code to the following.
If you perform the same test as before, when BadClass.MyData.ToString() is called for the second request, it will throw a System.NullReferenceException exception. The System.NullReferenceException exception occurs because the first request set the value to null while the second request was waiting. The resolution for this behavior is the same as for a static property.
Memory leak caused by static eventsIf you set up a static event and then subscribe to that event from an .aspx page, the process will eventually run out of memory. Let's consider you add the following to the BadClass.cs file.
You then wire up the event delegate in the InitializeComponent method of the .aspx page to a method in the page.
You also add the following method to your page. This is the method that you specified when hooking up the event in the InitializeComponent method:
Why this causes a memory leakBecause the event is static and never goes out of scope, you are adding the method to the list of events that are fired when the event occurs each time the page is run. The end result of this is that whatever object you wire to the static event is rooted in memory, and it will never be collected. In this case, that object is the actual .aspx page class.
This behavior occurs in the Windbg.exe debugger or the Cdb.exe debugger by running the !gcroot command on the object that you are adding the event from. You will see output that is similar to the following.
Many object requests have been made to the following events.
You can see that the bottom item is the .aspx page class, and it is rooted to multiple MyEvent delegates. Because the .aspx page is rooted, it cannot be cleaned up. The other side effect is that whatever the .aspx page is using also cannot be cleaned up because they are rooted in the page object.
For more information about the Microsoft .NET garbage collector, visit the following MSDN Web sites:
http://msdn.microsoft.com/msdnmag/issues/1200/GCI2/default.aspxFor more information about the !gcroot command and obtaining this output, see the ".NET CLR Memory Counters" section of the following MSDN Web site:
Avoid this behaviorTo avoid this behavior, you can either not use the static keyword on the event or remove the event handler from the page when you are done using it. In an ASP.NET example, you wire the event when Page_Init is called. You must remove it when the page unloads by adding an event handler for the Page_Unload event.
Add the following to the InitializeComponents method.
For more information about events, visit the following MSDN Web site:
As always, feel free to submit ideas on topics you want addressed in future columns or in the Knowledge Base using the Ask For It