I’ve never understood why IIS by default configures newly created application pools to recycle every 1740 minutes. That means that by default, our ASP.NET applications are restarted every 29 hours. And for what? Are we, the .NET community, so bad that we really can’t write code that can keep running without problems for more than 29 hours? Well, considering the overall lack of knowledge regarding memory management in .NET, I actually wouldn’t be surprised if that turned out to be the case for a very large portion of .NET development teams.
And indeed, if you browse the web to find the reason why application pools are configured to recycle automatically periodically, you’ll be hard pressed to find a reasonable answer that doesn’t pertain to memory issues. It’s like the community in general has pretty much accepted the fact that our web applications (or service layers hosted in IIS) will need to be recycled to avoid memory problems. To make things worse, I've frequently seen people discuss workarounds on how to keep things working properly after an application pool recycle in mailinglists for various projects. And again I ask myself: why?
I’ve always been of the opinion that if your code requires periodic restarts to keep working correctly, then something is clearly wrong. There is a bug in your code somewhere and you need to fix that, instead of restarting the process occasionally to make the problem ‘go away’. Guess what, it’s not going away, and if the load on your application increases, the problem will only pop up more frequently. So what are you going to do about that? Make the application pool recycle even more frequently? Put in another server to share the load? Perhaps we should focus more on fixing the actual code. You’re leaking resources somewhere, and that is what you need to fix.
In my company, it’s just standard procedure to disable application pool recycling on all application pools. Our applications simply have to keep working without application pool recycles. It’s that simple. If we run into a memory leak that causes problems, we focus on the actual problem and we fix it. We’ve ran into plenty of memory leaks (though it hasn’t really happened a lot in the past year, guess why?) and we’ve fixed each and every single one of them that we’ve ran into. Side note: I'm talking about .NET code that is running on the server. While I'm pretty sure that we do better at memory management in our Silverlight clients than most other Silverlight-using-shops do, you just never know for sure with Silverlight, partly because there are so many memory leaks in Silveright itself. But for .NET code running on a server, a memory leak is simply inexcusable in my opinion. I mean, it can happen to the best of us (i’m pretty much responsible for most of ours to be honest), but it’s not about who introduced the memory leak. It’s all about how you deal with it. And recycling the application pool periodically is not dealing with it, it’s living in denial.
The only viable reason to recycle application pools that I can think of is in the situation of a shared hosting provider. If you’re offering shared hosting, it only makes sense to recycle application pools occasionally since it’s quite realistic to assume that most of those application pools will not be in use constantly. If a pool is recycled, it will not consume any resources until the next request for an application in that pool is received. In the context of shared hosting, that actually makes sense. In the context of real applications, that makes little sense unless you’re hosting a lot of them and plenty of them are hardly being used. Still, is that really a good enough reason to enabling application pool recycling by default? I obviously don’t think so.
In my opinion, we, as a community, really need to start focusing more on memory management in .NET and on making sure that our applications can keep running without problems.
I dislike ViewState as much as the next guy, but when you're working with ASP.NET WebForms, you just can't avoid it. In some cases, the size of the ViewState can become so big that it significantly increases the load time of pages due to the extra bandwidth consumption. The correct solution would obviously be to reduce the size of the ViewState in those pages as much as you can, but it's not always feasible to do so. So we wanted a more general 'solution', and I found this post which discusses compressing the ViewState before you send it to the client and decompressing it when the client sends it back. We used pretty much the same approach, but with some differences.
First of all, ViewState is persisted in the resulting HTML page through an IStateFormatter object. We'll provide our own CompressedStateFormatter which implements the IStateFormatter interface, and uses the standard IStateFormatter that ASP.NET uses:
The idea is very simple: when the Serialize method is called, we first call the real formatter's Serialize method, compress its return value and then return the Base64-encoded string of the compressed serialized state. And in the Deserialize method, we do the exact opposite: we first decompress the Base64-encoded string and then we use the real formatter to deserialize the actual ViewState.
In Mamanze's example, he checks to see if the compressed version is actually smaller than the decompressed version and if so, uses the decompressed version instead of the compressed one. And when decompressing he first checks to see if it's a compressed or decompressed version and obviously only decompresses in case of a compressed version. The only page where I found the compressed version of the ViewState to be larger than the decompressed version was in our log in page, so I just got rid of that piece of the code.
Now we still have to plug this into ASP.NET's behavior somehow... first we add a pagestate.browser file to the App_Browsers folder of your web application (if it doesn't exist, just create it) with the following content:
The CompressedPageStateAdapter looks like this:
And the CompressedHiddenFieldPageStatePersister class looks like this:
The HiddenFieldPageStatePersister is the class that ASP.NET WebForms will use by default to store your ViewState into a hidden field in the resulting HTML. By default, the HiddenFieldPageStatePersister uses the default IStateFormatter type that ASP.NET uses, which only uses Base64 encoding but no compression. Unfortunately, there is no clean way to instruct ASP.NET to use a different implementation for IStateFormatter, so we need to use a bit of reflection to overwrite the value of HiddenFieldPageStatePersister's _stateFormatter field. Luckily, this also enables us to first get the value of the StateFormatter property so we can pass this reference (which is the 'real' formatter) to our CompressedStateFormatter.
And that is all there is to it... all of your pages will now use this CompressedHiddenFieldPageStatePersister so you get the benefit of ViewState compression in each of your pages. You can also do this selectively if you want, by not using the pagestate.browser file and overriding the PageStatePersister property of your ASPX page:
This way, only the pages that contain this code will use the CompressedHiddenFieldPageStatePersister.
Instead of inheriting from HiddenFieldPageStatePersister, you could also inherit from SessionPageStatePersister. SessionPageStatePersister will store your ViewState in the HttpSessionState, and will only include a little bit of ViewState in your HTML page instead of everything. But you do need to be aware of the fact that using the CompressedStateFormatter when inheriting from SessionPageStatePersister will only result in compressing the little bit of ViewState that is included in the HTML, and not the ViewState that is stored in the HttpSessionState.
In case you're wondering: why should I use this instead of using typical HTTP compression on the IIS level? I believe it has a couple of advantages to HTTP compression. First of all, AFAIK, HTTP compression does not have any benefit on postbacks. And since ViewState is always posted back to the server, this can make a pretty big difference. Also, with this approach, the client will not have to decompress the entire ViewState (which isn't used client-side anyway) and the browser doesn't have to waste time on it in general.
I haven't used this in production yet, but I will very soon... unless someone knows of a good reason why I shouldn't ;)
One of my coworkers describes a very interesting memory leak he just fixed. Be sure to read his post to get the entire story.
We basically had a custom UserControl which contained (among other things) a Repeater which would render another custom UserControl. Nothing really weird there, right? The problem was that the custom UserControl that was created by the Repeater explicitly needed to be disposed. No problem, System.Web.UI.Control implements IDisposable so we could just override the Dispose method, perform our cleanup there and then proceed with the base Dispose implementation.
Now, I'm far from an ASP.NET expert but I was under the impression that all Page and UserControl instances would always have their Dispose method called if they were created by other ASP.NET controls (containing pages or controls). After all, what's the point in implementing IDisposable in the base Control class if you're not even going to guarantee proper usage of the pattern, right?
Well, as Kristof describes in his post, there is at least one situation where a UserControl is not disposed of, even though it was created by a Repeater. In our case, the leak was subtle. It took a stress test of 10 hours with a load that would be comparable to real world usage of one month to expose the leak. A lot of people would say "oh, let's just recycle the application pool periodically and everything is A-OK". But the very idea of having to recycle an application pool periodically to keep a system up and running is just a cop out to me. Good code should not require periodic restarts. Period.
I wonder how many ASP.NET WebForms applications might actually have the same (or at least similar) problem(s) like the one Kristof encountered. If everyone keeps recycling their application pools periodically, we unfortunately may never found out.
Sometimes it's useful to be able to store an object somewhere so you can easily access it for the duration of the current request, instead of having to pass it around with every method call that you make. That request could be an ASP.NET request, or a request in your WCF service layer. I used to resort to storing these objects in ThreadStatic fields (which is basically a static reference for each thread), thinking that it would be safe because only one thread handles a complete request. Last week I read that some requests can be paused and resumed by another thread. If you're using ThreadStatic fields, this could lead so major issues which would be a royal pain in the ass to debug. In order to prevent this possible problem, I wanted to have a safe way to keep state that should be available for the duration of a single request.
If your code executes in an ASP.NET environment, you can safely use the HttpContext.Current.Items dictionary for this. If your code executes in a WCF environment, you can store these things in the OperationContext. I don't want my code to be tightly coupled to either ASP.NET or WCF, so I wanted some kind of abstraction. This is the approach that I came up with.
First, we have the IRequestState interface:
This just offers a way to store objects and retrieve them. That's pretty much al we need, right?
Then we have the ASP.NET implementation:
Very simple stuff... the AspNetRequestState implementation simply uses the HttpContext.Current.Items dictionary underneath to store and retrieve the objects.
For WCF, it is slightly more complicated. Every WCF call is an operation and it has a context as well, which is provided through the OperationContext class. The OperationContext class doesn't have an Items dictionary like HttpContext does, but it does have a way to add extensions to the context. We can use this extensions mechanism to store state which should be kept around for the duration of the current WCF operation. First, we need to define our Extension:
The IExtension interface that we must implement defines the Attach and Detach methods but we don't really need them for what we're trying to do. This extension simply initializes a Dictionary instance and exposes it with a public getter. Now we can easily create our WcfRequestState implementation:
Pretty simple as well, and pretty similar to the AspNetRequestState implementation. The AspNetRequestState implementation is able to simply use the HttpContext.Current.Items dictionary, which we can't use here. So when we want to access the 'State' dictionary in this implementation, we look it up in the current OperationContext's Extensions collection. If it's not there yet, we add a new instance of our MyExtension class to the OperationContext's Extensions collection.
Now we can use this wherever we need to store something for the duration of the current request, regardless of whether we're executing in an ASP.NET or WCF context. Just configure your IoC container to create instances of AspNetRequestState whenever an IRequestState instance is needed in your WebApplication, or configure it to return WcfRequestState instances in your WCF service. The code that needs to store some request state will no longer have to resort to using ThreadStatic fields, and it doesn't need to know about it's runtime environment either. It merely needs an instance of IRequestState.
Ever since I wrote my How To Write Testable ASP.NET WebForms post I've had people asking me how to make it work with UserControls. I pretty much avoided UserControls with this approach for as long as I could, but for our current project we really had a need for it. So I started implementing this together with a coworker, and this is the solution we came up with.
Note: if you haven't read that post on how to write testable ASP.NET WebForms, be sure to read it first because this approach is very similar and I won't repeat all of the general concepts of the approach here.
In the implementation for WebForms, we call the pages Views, and they all implement their own interface which inherits from our own IView interface. Now we wanted something that would work both with UserControls and Web Parts. So we figured we should call both of them ViewParts and we have the following base interface that each ViewPart should implement:
If you need more operations that each ViewPart should be able to offer, you can obviously just add whatever you want to this interface.
We also want each ViewPart to have its own Controller, which we call PartControllers. Since we want to be able to test both the ViewParts and their containing Views in isolation, each View's Controller can never communicate directly with the specific PartController(s) of the ViewPart(s) that it contains. So we first need the following base interface for each PartController:
In our case, each PartController will need an IDispatcher instance to be able to communicate with our Request/Response Service Layer. So the IDispatcher reference is only necessary if you're using that as well. The idea is that the containing View's Controller needs to provide its IDispatcher instance to each contained ViewPart's PartController so the initial requests of each ViewPart can be sent to the service layer together with whatever initial requests the containing View's Controller needs to send when the View is loaded. That's basically what the AddInitialRequests and GetInitialResponses methods are for. Again, this is very specific to the usage of the Request/Response Service Layer, so you might want to put some entirely different basic operations in your base IPartController interface.
We need to be able to ask each ViewPart for its typed PartController, so we also have this interface:
We also need to be able to ask each PartController for a typed instance of its ViewPart, so we also have the following interface:
And then our PartController base class looks like this:
Now, when we want to write UserControls that can work with this approach, we need to inherit from the following UserControl base class:
When the UserControl is constructed, we retrieve an instance of the specific PartController through the IOC container, and we pass the newly created instance of our UserControl as the ViewPart dependency of the PartController.
What you've seen so far is all very abstract, so let's go over a small example. Suppose we have a View (DummyPage) which contains a ViewPart (DummyPart). First, let's create the DummyPart:
Our DummyPart (the ViewPart) inherits from our UserControl base class and passes the interface type of our PartController as the type parameter of the UserControl. It also implements the IDummyViewPart interface (which is empty in this simple example):
The IDummyViewPartController interface looks like this:
The implementation of the DummyPartController looks like this:
So what do we have now? A reusable UserControl which has its own controller where the actual logic of the UserControl will be implemented. We can write unit tests for all of the logic that the UserControl needs to have. We can also reuse this UserControl in a Page, and do so in a manner which enables us to fake the implementation of the UserControl for the tests we'll write for the logic in that Page.
Suppose we have a DummyPage which contains the DummyPart UserControl. Our DummyPage implements the following interface:
The code of our actual DummyPage looks like this:
And the code of the DummyController looks like this:
In the Load method of the DummyController, we retrieve the DummyPartController and we can communicate with it. And since we're talking to an interface type, we can easily provide a mocked IDummyPartController instance for our unit tests.
This approach makes it possible to create UserControls which you can easily write unit tests for, and you can reuse the UserControls in containing pages while remaining the flexibility to write unit tests for those containing pages without being dependent on the actual implementation of the UserControl.