I've got two different, but closely related ASP.Net web applications that use the same data on some pages. In both applications I am using the ObjectDataSource control, have EnableCaching="true", and use the same CacheKeyDependency value in both applications.
I would like to make it so that when a new record is inserted or deleted in one application, it clears the cache in both applications. I began by simply clearing cache by using Page.Cache, but soon realized that it does not clear the cache in the other application. Then I added a WCF service to each application; each service clears the cache object in the application it is hosted in. Except that it doesn't...
First, I discovered that System.Web.HttpContext is always null in WCF. Then I tried instantiating a System.Web.Routing.RequestContext object, but its HttpContext object is always null as well.
It all boils down to this: If I set a Page.Cache object, can a WCF service access that same cache object, if the service is hosted in the same application as the page?
Yes, you need to enable ASP.NET integration for the WCF service. This involves setting the aspNetCompatibilityEnabled attribute for the serviveHostingEnvironment element in config as well as adding the AspNetCompatibilityRequirementAttribute attribute to you service class to indicate that you support it.
More on this subject can be found here on MSDN.
The main challenge with cache in two applications is that the cache can be stored on seperate machines, or if they are on the same machine, in different application pools.
One way you can do this is to allow both applications to use the same cache. One solution for a distributed cache that runs out of process is Appfabric caching.
Related
I'm trying to eliminate (or at least minimize) startup/warmup times for my .NET applications. I'm not really sure on how to do this even though it's a common concern.
There's a ton of questions about slow startup of .NET applications. These are easily explained by pool recycles, worker process startup, dynamic compilation of .aspx files, JIT etc. In addition, there are more things that may need to be initialized within the application such as EntityFramework and application caches.
I've found alot of different solutions such as:
ASP.NET Precompilation
IIS 8 Application Initialization (and for IIS 7.5)
Auto-Start ASP.NET Applications
However, I'm not entirely satisfied with any of the solutions above. Furthermore I'm deploying my applications to Azure Websites (in most cases) so I have limited access to the IIS.
I know that there are some custom "warmup scripts" that uses various methods for sending requests to the application (e.g. wget/curl). My idea is to create a "Warmup.aspx" page in each of my ASP.NET applications. Then I have a warmup service that sends an HTTP GET to the Warmup.aspx of each site every ... 5 minutes. This service could be a WorkerRole in Azure or a Windows Service in an on-premise installation. Warmup.aspx will will then do the following:
Send an HTTP GET to each .aspx-file within the application (to
dynamically compile the page)
This could be avoided by precompiling the .aspx pages using aspnet_compiler.exe
Send a query to the database to
initialize EntityFramework
Initialize application caches etc
So, my final question is whether there are better alternatives than my "Warmup.aspx" script? And is it a good approach or do you recommend some other method? I would really like some official method that would handle the above criteria.
Any and all suggestions are welcome, thanks!
Did you try this IIS Auto-Start feature described here ?
https://www.simple-talk.com/blogs/2013/03/05/speeding-up-your-application-with-the-iis-auto-start-feature/
You could have two instances of the site. When you need to deploy a new version, and therefore suffer a startup cycle, remove one instance out of load balancer rotation, deploy and start it, set it in and do the same for instance 2. A rolling deployment.
Is it possible to have a central cache for an ASP.NET web application that is accessed using multiple domain names? The web application is using a single website and application pool, with multiple domains (host headers) pointing to it.
A bit of background - the application has a lot of data that doesn't change much, and to alleviate database load, I've been storing this in static variables. This has been working without any problems when there is only a single domain. However, with multiple domains, it seems that each domain name being used to access the website has its own copy of this data, so when it's invalidated in one site, the others still retain their own version causing it to never be updated.
I've tried changing this to use HttpRuntime.Cache instead of static variables, but this also exhibits the same problem where each domain being used to access the site seems to be storing its own version of the data.
Is there any way to cache data within an ASP.NET web application that can be shared (and invalidated) across all domains being used to access it?
Try memcached. You can use the BeIT .Net API.
Memcached runs as a stand-alone service and is meant to facilitate distributed caching. It runs under windows and under Linux.
You could create a table in memory in your database and have all the applications pull from that. It should work essentially the same as your cache does now.
What is the difference between System.Web.Cache and HTTPContext.Curent.Cache? In which cases both are used?
System.Web.Caching.Cache: this is the
implementation of .NET caching.
System.Web.HttpContext.Current.Cache:
this is the instance of that
implementation, that lives in the
application domain.
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.
From msdn article
System.Web.Cache is the class of the caching, and HttpContext.Current.Cache is a property that returns a reference to the caching object in the application.
The Page, UserControl and HttpResponse objects also have a Cache property that you can use to get the reference. You can also get the reference from HttpRunTime.Cache.
System.Web.Caching.Cache is class that handles cache and HttpContext.Cache is property, that contains an instance of System.Web.Caching.Cache for current context.
System.Web.Caching.Cache is the implementation of .NET caching (1).
System.Web.HttpContext.Current.Cache is the instance of that implementation, that lives in the application domain (1).
(1): Reference
I have a component (an assembly built in .net) that i need to access on (almost) every request to two different websites. One website is written in classic asp and the other one in asp.net mvc.
At the moment i reference the assembly in the asp.net solution and call it like i would any .net assembly. On the classic asp website, i call it through a COM wrapper.
This is all good, except now i need this component to actually stay alive and monitor changes to a configuration file. In my asp.net website i could keep a refence in the application scope and i guess i could register it in component services for the asp access.
Is this the best way to do it? Also, this way the component would actually be hosted twice - one instance in the asp.net application scope and one in the component services. I could perhaps instead only have it live in component services, and then instead reference it from asp.net.
I don't know - something smells fishy (and no, it's not me) - am i on the right track or do you see better alternatives?
Do you really need a long running object? You say you need to monitor configuration file changes -- when the config changes do you need to trigger some actions or do you just need to ensure that each incoming request uses the latest copy of the configuration for your component? If it is the latter then standard .NET configuration should work for you without concern for the object lifetime.
In terms of hosting, do you need to use any COM+ services? If not, then I would not use COM+. If you want one central location for your .NET component, why not register it in the GAC?
Ok so i think i found two solutions, both acceptable for this project:
1) Register it in global.asa on the Application_OnStart in the Application object like this Application("Someobject") = Server.CreateObject("Someobject")
2) Host it in component services and handle lifetime there.
I am working with a custom role provider in asp.net and it appears that once the provider is loaded into memory, it doesn't drop out of memory until the web application is restarted (like when the web.config file is changed and saved). Further, all of the requests to that web application seem to utilize the one instance of the role provider.
So my question is: When does asp.net create instances of role providers? And what is their life span? When does asp.net create new instances? And is there a way to force asp.net to refresh the current provider instance by dropping the old instance and creating a new one?
The design of ASP.NET assumes the providers are stateless objects. Therefore, you should design your provider in a manner that you won't need to know about when it is created and when it dies. Basically, if you really want to do that, you could put the actual logic in a different class that its creation and disposal will be handled by a proxy class that you introduce to ASP.NET.
Also, ASP.NET does not guarantee when it will create the role provider object. It's something like static constructors. You should only rely on the fact that they do exist whenever they are needed.