Basically I know what the difference is. Also, I do know (as you all) there is a lot of resources discussing the issue (e.g. here).
But today, I heard an strange and weird idea which says Add method, adds the object to application-scope cache, while the Insert method will adds the object to the session-scope cache!!!
I mean HttpContext.Current.Cache.Add will add object to a shared memory which is accessible for all users/threads/sessions/requests/etc.
But HttpContext.Current.Cache.Insert will add the object to a session-dependent cache (which actually would be the session itself. right? :D)!!!
It's the first time I'm hearing such a thing. I did search the msdn and technet.microsoft.com. I also did decompile the Cache class (via dear ReSharper) and read the entire code (and it's dependencies). But nothing came out which make a dependency between Cache and Session.
I'm just asking. Is there any relationship between Cache and Session?
Note: The app is running on a web garden in a Win 2012 R2 machine with IIS 8.5.
There are separate and in a different scope to each other.
As far as I can see, both Methods are applicable to the Cache object and calling Add will not have any interaction with the Session object
Related
I have to work on already developed solution which is using NHibernate (v1.2.1.4000) with SQL Server 2008.
The application is using .NET Framework 2.0 due to Membership authentication and other stuffs.
This is working in Visual Studio - I can debug it, run in. But failed when deployed in IIS (v8.0)
Exception is:
Duplicate type name within an assembly.
HibernateException: Creating a proxy instance failed.
And it occurred whenever database is fetched to get some models.
I have googled on this issue and have some suggestion to use nhiberante (v3.3.x).
But the lots of interfaces and method parameters are different in v3. so it is breaking implementaion of the source code.
Several questions regarding this exist on stackoverflow but no luck yet
Maybe you have a concurrency trouble, something like singleton initialization failing to ensure uniqueness of its initialization, occurring only under load.
Especially check your session factory. Put logs when building it, check it is not built multiple times. Try triggering your singleton initializations from Application_Start if they are not already triggered from there.
Avoid singleton lazy initializations unless they are really heavy and not needed for most of you application HTTP requests. In such case, make sure their logic is thread safe and avoid running concurrent initializations (something like LazyThreadSafetyMode ExecutionAndPublication instead of PublicationOnly: it requires stricter locking but must be done that way for building the ISessionFactory, if it is done through lazy initialization.)
I'm wondering if there are any differences between MemoryCache and HttpRuntime.Cache, which one is preferred in ASP.NET MVC projects?
As far as I understand, both are thread safe, API is from first sight more or less the same, so is there any difference when to use which?
HttpRuntime.Cache gets the Cache for the current application.
The MemoryCache class is similar to the ASP.NET Cache class.
The MemoryCache class has many properties and methods for accessing the cache that will be familiar to you if you have used the ASP.NET Cache class.
The main difference between HttpRuntime.Cache and MemoryCache is that the latter has been changed to make it usable by .NET Framework applications that are not ASP.NET applications.
For additional reading:
Justin Mathew Blog - Caching in .Net 4.0
Jon Davis Blog - Four Methods Of Simple Caching In .NET
Update :
According to the users feedback, sometimes Jon davis blog is not working.Hence I have put the whole article as an image.Please see that.
Note : If it's not clear then just click on the image.After that it'll open on a browser.Then click again on it to zoom :)
Here is Jon Davis' article. To preserve readability, I'm cutting out the now obsolete EntLib section, the intro as well as the conclusion.
ASP.NET Cache
ASP.NET, or the System.Web.dll assembly, does have a caching mechanism. It was never intended to be used outside of a web context, but it can be used outside of the web, and it does perform all of the above expiration behaviors in a hashtable of sorts.
After scouring Google, it appears that quite a few people who have discussed the built-in caching functionality in .NET have resorted to using the ASP.NET cache in their non-web projects. This is no longer the most-available, most-supported built-in caching system in .NET; .NET 4 has an ObjectCache which I’ll get into later. Microsoft has always been adamant that the ASP.NET cache is not intended for use outside of the web. But many people are still stuck in .NET 2.0 and .NET 3.5, and need something to work with, and this happens to work for many people, even though MSDN says clearly:
Note: The Cache class is not intended for use outside of ASP.NET applications. It was designed and tested for use in ASP.NET to provide caching for Web applications. In other types of applications, such as console applications or Windows Forms applications, ASP.NET caching might not work correctly.
The class for the ASP.NET cache is System.Web.Caching.Cache in System.Web.dll. However, you cannot simply new-up a Cache object. You must acquire it from System.Web.HttpRuntime.Cache.
Cache cache = System.Web.HttpRuntime.Cache;
Working with the ASP.NET cache is documented on MSDN here.
Pros:
It’s built-in.
Despite the .NET 1.0 syntax, it’s fairly simple to use.
When used in a web context, it’s well-tested. Outside of web contexts, according to Google searches it is not commonly known to cause problems, despite Microsoft recommending against it, so long as you’re using .NET 2.0 or later.
You can be notified via a delegate when an item is removed, which is necessary if you need to keep it alive and you could not set the item’s priority in advance.
Individual items have the flexibility of any of (a), (b), or (c) methods of expiration and removal in the list of removal methods at the top of this article. You can also associate expiration behavior with the presence of a physical file.
Cons:
Not only is it static, there is only one. You cannot create your own type with its own static instance of a Cache. You can only have one bucket for your entire app, period. You can wrap the bucket with your own wrappers that do things like pre-inject prefixes in the keys and remove these prefixes when you pull the key/value pairs back out. But there is still only one bucket. Everything is lumped together. This can be a real nuisance if, for example, you have a service that needs to cache three or four different kinds of data separately. This shouldn’t be a big problem for pathetically simple projects. But if a project has any significant degree of complexity due to its requirements, the ASP.NET cache will typically not suffice.
Items can disappear, willy-nilly. A lot of people aren’t aware of this—I wasn’t, until I refreshed my knowledge on this cache implementation. By default, the ASP.NET cache is designed to destroy items when it “feels” like it. More specifically, see (c) in my definition of a cache table at the top of this article. If another thread in the same process is working on something completely different, and it dumps high-priority items into the cache, then as soon as .NET decides it needs to require some memory it will start to destroy some items in the cache according to their priorities, lower priorities first. All of the examples documented here for adding cache items use the default priority, rather than the NotRemovable priority value which keeps it from being removed for memory-clearing purposes but will still remove it according to the expiration policy. Peppering CacheItemPriority.NotRemovable in cache invocations can be cumbersome, otherwise a wrapper is necessary.
The key must be a string. If, for example, you are caching data records where the records are keyed on a long or an integer, you must convert the key to a string first.
The syntax is stale. It’s .NET 1.0 syntax, even uglier than ArrayList or Hashtable. There are no generics here, no IDictionary<> interface. It has no Contains() method, no Keys collection, no standard events; it only has a Get() method plus an indexer that does the same thing as Get(), returning null if there is no match, plus Add(), Insert() (redundant?), Remove(), and GetEnumerator().
Ignores the DRY principle of setting up your default expiration/removal behaviors so you can forget about them. You have to explicitly tell the cache how you want the item you’re adding to expire or be removed every time you add add an item.
No way to access the caching details of a cached item such as the timestamp of when it was added. Encapsulation went a bit overboard here, making it difficult to use the cache when in code you’re attempting to determine whether a cached item should be invalidated against another caching mechanism (i.e. session collection) or not.
Removal events are not exposed as events and must be tracked at the time of add.
And if I haven’t said it enough, Microsoft explicitly recommends against it outside of the web. And if you’re cursed with .NET 1.1, you not supposed to use it with any confidence of stability at all outside of the web so don’t bother.
.NET 4.0’s ObjectCache / MemoryCache
Microsoft finally implemented an abstract ObjectCache class in the latest version of the .NET Framework, and a MemoryCache implementation that inherits and implements ObjectCache for in-memory purposes in a non-web setting.
System.Runtime.Caching.ObjectCache is in the System.Runtime.Caching.dll assembly. It is an abstract class that that declares basically the same .NET 1.0 style interfaces that are found in the ASP.NET cache. System.Runtime.Caching.MemoryCache is the in-memory implementation of ObjectCache and is very similar to the ASP.NET cache, with a few changes.
To add an item with a sliding expiration, your code would look something like this:
var config = new NameValueCollection();
var cache = new MemoryCache("myMemCache", config);
cache.Add(new CacheItem("a", "b"),
new CacheItemPolicy
{
Priority = CacheItemPriority.NotRemovable,
SlidingExpiration=TimeSpan.FromMinutes(30)
});
Pros:
It’s built-in, and now supported and recommended by Microsoft outside of the web.
Unlike the ASP.NET cache, you can instantiate a MemoryCache object instance.
Note: It doesn’t have to be static, but it should be—that is Microsoft’s recommendation (see yellow Caution).
A few slight improvements have been made vs. the ASP.NET cache’s interface, such as the ability to subscribe to removal events without necessarily being there when the items were added, the redundant Insert() was removed, items can be added with a CacheItem object with an initializer that defines the caching strategy, and Contains() was added.
Cons:
Still does not fully reinforce DRY. From my small amount of experience, you still can’t set the sliding expiration TimeSpan once and forget about it. And frankly, although the policy in the item-add sample above is more readable, it necessitates horrific verbosity.
It is still not generically-keyed; it requires a string as the key. So you can’t store as long or int if you’re caching data records, unless you convert to string.
DIY: Build One Yourself
It’s actually pretty simple to create a caching dictionary that performs explicit or sliding expiration. (It gets a lot harder if you want items to be auto-removed for memory-clearing purposes.) Here’s all you have to do:
Create a value container class called something like Expiring or Expirable that would contain a value of type T, a TimeStamp property of type DateTime to store when the value was added to the cache, and a TimeSpan that would indicate how far out from the timestamp that the item should expire. For explicit expiration you can just expose a property setter that sets the TimeSpan given a date subtracted by the timestamp.
Create a class, let’s call it ExpirableItemsDictionary, that implements IDictionary. I prefer to make it a generic class with defined by the consumer.
In the the class created in #2, add a Dictionary> as a property and call it InnerDictionary.
The implementation if IDictionary in the class created in #2 should use the InnerDictionary to store cached items. Encapsulation would hide the caching method details via instances of the type created in #1 above.
Make sure the indexer (this[]), ContainsKey(), etc., are careful to clear out expired items and remove the expired items before returning a value. Return null in getters if the item was removed.
Use thread locks on all getters, setters, ContainsKey(), and particularly when clearing the expired items.
Raise an event whenever an item gets removed due to expiration.
Add a System.Threading.Timer instance and rig it during initialization to auto-remove expired items every 15 seconds. This is the same behavior as the ASP.NET cache.
You may want to add an AddOrUpdate() routine that pushes out the sliding expiration by replacing the timestamp on the item’s container (Expiring instance) if it already exists.
Microsoft has to support its original designs because its user base has built up a dependency upon them, but that does not mean that they are good designs.
Pros:
You have complete control over the implementation.
Can reinforce DRY by setting up default caching behaviors and then just dropping key/value pairs in without declaring the caching details each time you add an item.
Can implement modern interfaces, namely IDictionary<K,T>. This makes it much easier to consume as its interface is more predictable as a dictionary interface, plus it makes it more accessible to helpers and extension methods that work with IDictionary<>.
Caching details can be unencapsulated, such as by exposing your InnerDictionary via a public read-only property, allowing you to write explicit unit tests against your caching strategy as well as extend your basic caching implementation with additional caching strategies that build upon it.
Although it is not necessarily a familiar interface for those who already made themselves comfortable with the .NET 1.0 style syntax of the ASP.NET cache or the Caching Application Block, you can define the interface to look like however you want it to look.
Can use any type for keys. This is one reason why generics were created. Not everything should be keyed with a string.
Cons:
Is not invented by, nor endorsed by, Microsoft, so it is not going to have the same quality assurance.
Assuming only the instructions I described above are implemented, does not “willy-nilly” clear items for clearing memory on a priority basis (which is a corner-case utility function of a cache anyway .. BUY RAM where you would be using the cache, RAM is cheap).
Among all four of these options, this is my preference. I have implemented this basic caching solution. So far, it seems to work perfectly, there are no known bugs (please contact me with comments below or at jon-at-jondavis if there are!!), and I intend to use it in all of my smaller side projects that need basic caching. Here it is:
Github link: https://github.com/kroimon/ExpirableItemDictionary
Old Link: ExpirableItemDictionary.zip
Worthy Of Mention: AppFabric, NoSQL, Et Al
Notice that the title of this blog article indicates “Simple Caching”, not “Heavy-Duty Caching”. If you want to get into the heavy-duty stuff, you should look at dedicated, scale out solutions.
MemoryCache.Default can also serve as a "bridge" if you're migrating a classic ASP.NET MVC app to ASP.NET Core, because there's no "System.Web.Caching" and "HttpRuntime" in Core.
I also wrote a small benchmark to store a bool item 20000 times (and another benchmark to retrieve it) and MemoryCache seems to be two times slower (27ms vs 13ms - that's total for all 20k iterations) but they're both super-fast and this can probably be ignored.
MemoryCache is what it says it is, a cache stored in memory
HttpRuntime.Cache (see http://msdn.microsoft.com/en-us/library/system.web.httpruntime.cache(v=vs.100).aspx and http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx) persists to whatever you configure it to in your application.
see for example "ASP.NET 4.0: Writing custom output cache providers"
http://weblogs.asp.net/gunnarpeipman/archive/2009/11/19/asp-net-4-0-writing-custom-output-cache-providers.aspx
I'm not a hater of singletons, but I know they get abused and for that reason I want to learn to avoid using them when not needed.
I'm developing an application to be cross platform (Windows XP/Vista/7, Windows Mobile 6.x, Windows CE5, Windows CE6). As part of the process I am re-factoring out code into separate projects, to reduce code duplication, and hence a chance to fix the mistakes of the inital system.
One such part of the application that is being made separate is quite simple, its a profile manager. This project is responsible for storing Profiles. It has a Profile class that contains some configuration data that is used by all parts of the application. It has a ProfileManager class which contains Profiles. The ProfileManager will read/save Profiles as separate XML files on the harddrive, and allow the application to retrieve and set the "active" Profile. Simple.
On the first internal build, the GUI was the anti-pattern SmartGUI. It was a WinForms implementation without MVC/MVP done because we wanted it working sooner rather than being well engineered. This lead to ProfileManager being a singleton. This was so from anywhere in the application, the GUI could access the active Profile.
This meant I could just go ProfileManager.Instance.ActiveProfile to retrieve the configuration for different parts of the system as needed. Each GUI could also make changes to the profile, so each GUI had a save button, so they all had access to ProfileManager.Instance.SaveActiveProfile() method as well.
I see nothing wrong in using the singleton here, and because I see nothing wrong in it yet know singletons aren't ideal. Is there a better way this should be handled? Should an instance of ProfileManager be passed into every Controller/Presenter? When the ProfileManager is created, should other core components be made and register to events when profiles are changed. The example is quite simple, and probably a common feature in many systems so think this is a great place to learn how to avoid singletons.
P.s. I'm having to build the application against Compact Framework 3.5, which does limit alot of the normal .Net Framework classes which can be used.
One of the reasons singletons are maligned is that they often act as a container for global, shared, and sometimes mutable, state. Singletons are a great abstraction when your application really does need access to global, shared state: your mobile app that needs to access the microphone or audio playback needs to coordinate this, as there's only one set of speakers, for instance.
In the case of your application, you have a single, "active" profile, that different parts of the application need to be able to modify. I think you need to decide whether or not the user's profile truly fits into this abstraction. Given that the manifestation of a profile is a single XML file on disk, I think it's fine to have as a singleton.
I do think you should either use dependency injection or a factory pattern to get a hold of a profile manager, though. You only need to write a unit test for a class that requires the use of a profile to understand the need for this; you want to be able to pass in a programatically created profile at runtime, otherwise your code will have a tightly coupled dependency to some XML file on disk somewhere.
One thing to consider is to have an interface for your ProfileManager, and pass an instance of that to the constructor of each view (or anything) that uses it. This way, you can easily have a singleton, or an instance per thread / user / etc, or have an implementation that goes to a database / web service / etc.
Another option would be to have all the things that use the ProfileManager call a factory instead of accessing it directly. Then that factory could return an instance, again it could be a singleton or not (go to database or file or web service, etc, etc) and most of your code doesn't need to know.
Doesn't answer your direct question, but it does make the impact of a change in the future close to zero.
"Singletons" are really only bad if they're essentially used to replace "global" variables. In this case, and if that's what it's being used for, it's not necessarily Singleton anyway.
In the case you describe, it's fine, and in fact ideal so that your application can be sure that the Profile Manager is available to everyone that needs it, and that no other part of the application can instantiate an extra one that will conflict with the existing one. This reduces ugly extra parameters/fields everywhere too, where you're attempting to pass around the one instance, and then maintaining extra unnecessary references to it. As long as it's forced into one and only one instantiation, I see nothing wrong with it.
Singleton was designed to avoid multiple instantiations and single point of "entry". If that's what you want, then that's the way to go. Just make sure it's well documented.
I'm having some trouble recently.
On a WebForm I declare a static object, like this :
public static MyObject myobject=new MyObject();
Response.Write(myobject.Title());
now, if I load another page that doesn't contain the declaration of myobject and I do again
Response.Write(myobject.Title());
I see the previosly result. Is the object stored on session during the navigation due to the static? And it's reckon by the VIEWSTATE? Or what's happening?
No it's stored as a static variable in the process, which can be recycled at any point, assuming you use IIS.
In short, try not to use static variables in this situation.
To expand on what is happening. The static variable is stored in the server's process, which is controlled by IIS. It just so happens that the process is still alive when you call back onto the server. IIS can recycle this process at any time.
Update: OK more accurately it is per AppDomain, which sits in a process - substitute the word process with AppDomain in my previous paragraphs :-)
It's just a static variable. It "lives" alongside the type - so it will be shared by all code accessing the same field via the same type in the same AppDomain. It will be lost on AppDomain recycle, and won't be shared across multiple servers, etc.
Basically it's not a good idea to use static variables in webapps other than occasionally for local caching...
Static objects are shared across users. It is not stored in session which is unique to user or view state which is unique to each page.
Read up on ASP .NET State Management Recommendations to find out which type of state management feature to use for which scenario.
If it helps, I tend to take the view that you can declare two separate objects within one class - the dynamic object definition and the static object. Normally, if you are creating these within the same class definition, there is a connection between them, and they work in tandem ( the singleton patten is a prime example ).
What it means is that the object is created based on the dynamic object. There is still a static object unaffected by the creation of the dynamic object(s). Because this can be confusing, you should not combine the two without being careful and understanding the distinction between them.
I realise that this is not a real understanding of what is happening, but it helps me to keep in my head the distinction. Each type has its own use, and should be used appropriately ( I have seen dynamic classes that should have been static, as well as the other way round ).
I have ran into an issue with my SQL instance store attached to a WorkflowApplication that is running. When I exit my application I'm calling an Unload() on the WF app to persist it. I didn't think about it during design time, but it does makes sense, it's persisting an arg that was passed in to the WorkflowApplication constructor when instanced.
When the application runs, everything in the workflow works as expected. When I call Unload() I get an unhandled exception that states that the arg is not serializable and needs [DataContractAttribute].
What's passed into the workflow is my applications custom logger object that I wrote so that the WF can log to disk in a uniform way that I prefer. How do I prevent the workflow app from persisting this one argument and persist everything else?
I'm sure something can be done with extensions but I'm having a hard time finding info on them or finding persistence examples for my scenario.
You can decorate the variable to not be serialised, with a [NonSerialized] attribute.
That should do the trick, it worked for me in a WF3.5 app. See http://msdn.microsoft.com/en-us/library/ms973893.aspx, heading "Selective Serialization"