I understand that in order for a ASP.Net handler to support session state you need to implement both IHttpHandler and IRequireSessionState, but why isn't session state provided by default? If for performance reasons, then wouldn't it be better to have an interface like IDoesNotRequireSessionState?
Its because the session is block the asynchronous operations, and the handle is usually used for long time operations, like the making and download of a file - if you keep the session on long time operation you block the rest of your pages.
Also the handle is made with the idea of the minimum required to get a response.
About the session lock:
Web app blocked while processing another web app on sharing same session
jQuery Ajax calls to web service seem to be synchronous
ASP.NET Server does not process pages asynchronously
Replacing ASP.Net's session entirely
If for performance reasons, then wouldn't it be better to have an
interface like IDoesNotRequireSessionState?
Absolutely not, because then everybody implementing a handler must know about the existence of this interface. An HTTP handler is the fastest in terms of performance you might ever get from ASP.NET. So if you want to pollute it with crap like session then you'd better do it explicitly, and taking full responsibility of doing so, by implementing some interface that you should know about.
Related
I am trying to understand the various ways of storing and instantiating Application (i.e. objects available to every user) and Session level (objects created and available to users only for their session) variables. Also, how does OWIN fit into all of this?
Global.asax.cs - This can contain a bunch of different methods. I believe that Application_Start is only called during the first request. However, there are a few candidates here for methods to populate session level variables (e.g. Session_Start and Application_BeginRequest). What is the standard way of doing this?
There is also the Startup class used by OWIN. I get that OWIN lets you store Application level variables, but why wouldn't you just use the HttpApplicationState Application variable accessible from Global.asax.cs to accomplish this? Also - can OWIN handle Session variables?
"I believe that Application_Start is only called during the first
request."
Only for the first request after calling the web application. For instance, this is the case after deploying, ApplicationPool Recycling, restarting or coming out of sleep.
Let's assume 3 users visit your web application. Application_Start will only be called for one of them, specifically the first one that visits it. Therefore it is not suited for populating user-specific session values.
However, there are a few candidates here for methods to populate session level variables (e.g. Session_Start and Application_BeginRequest). What is the standard way of doing this?
In the past I've worked with Session_Start to initialize user-specific session values (like default values) on numerous projects and never had an issue with it.
I'm really not sure what the question is, as I said in the comments. I'm going to ignore the OWIN stuff since I don't know, frankly.
Firstly, try not to store state at all. Design to pass state back and forth between server and client in models, or the URL, even in the HTML on the client such as in the URLs in the <a> tags your rendering, or (rarely) in cookies, rather than keep things in memory. Stateless designs are way more scalable.
Storing state isn't "usually" done in the Global.asax but then what's usual? I store state as and when I need it, load it or otherwise come by that data. For me in MVC, that's usually downstream of a Controller action, maybe while logging someone in, or reading some data received in a model, like a customer clicking 'add to cart'.
Application state I rarely use, though I store long-lived and shared data within normal fields and properties in long-lived static classes. These die when the app is recycled, but I don't usually care since the apps are designed to work without it, stateless; its usually cached bits of data.
Also, Session_Start only fires when a new browser/agent hits the site. You don't know the user at that point.
The methods in the Global.asax were not specifically designed for 'bootstrapping' state-loading, they're just convenient events for doing whatever you want with. You don't have to use them at all, mine usually just contain logging so I know when sessions start etc.!
I don't know if this helps.
Once you have a plan, come back and ask a targeted question about the OWIN stuff.
I have an asp.net 3.5 web application which generates alot of audit related data. Since that data isn't immediately relevant to the user, I'd like to be able to save it to the MSSQL database asynchronously and let the user go onto the next page without waiting. I'm using Nhibernate as my ORM.
I've looked into PageAsyncTasks and as far as I can tell they simply allow you to perform page operations in parallel, but all operations still have to complete before the page finishes loading. Is there an alternative, fairly lightweight method to have asynchronous processing that will continue on without affecting page load? Is simply spinning up a new thread manually an acceptable process?
You could create a web service within your solution and when your server-side code is finished and ready to move the user on to the next page it could call your web service to do the auditing as a fire and forget type thing.
Not sure if the NHibernate session is threadsafe so if you create a new thread be careful with the context.
Ideally you could use queues and a servicebus to deal with this sort of thing safely and async but that involves architectural changes.
Not sure if this is possible but if the auditing is actually noticeably slowing the UI down maybe you'd be better off to improve that process and keep it synchronous. Either way, good luck.
I'm having problems because of a poorly written third-party library which our system heavily depends on. This library is not thread-safe (because of some bugs and static variables) and I need to use it in a ASP.NET webservice, which handles each user request in a separate thread.
I've tried many solutions for this problem. The best solution for now is, in my opinion, let subprocesses handle the requests. One subprocess will listen and handle the requests for one user, so I can synchronize access to the library code in a per user fashion, which is much better than all that I can do when sharing static variables between requests.
How can I route requests received by IPC communication to the appropriate WebMethods without reinventing the wheel? If possible, I would like to use the classes from .Net that handle this in a normal ASP.NET webservice, but I'm having a hard time trying to find their names.
TL;DR: I have a class MyWebService (that inherits from System.Web.Services.WebService) with some methods marked with WebMethodAttribute and I want to pass a made-up HttpRequest (or HttpContext) to it and tell it "handle it like you're receiving this from a real HTTP server, despite the fact the current process is a console application".
First, you may want to consider using WCF instead of ASMX, which is a legacy technology, kept only for backwards compatibility.
Second, you have another option: ensure that only a single thread ever uses the third-party libarary at a time. Placing lock blocks around all access to the third-party library may solve the problem.
I've just read this interesting article regarding simultaneously calling multiple methods on a WCF service from Silverlight:
http://weblogs.asp.net/olakarlsson/archive/2010/05/20/simultaneously-calling-multiple-methods-on-a-wcf-service-from-silverlight.aspx
The article states: "It turns out that the issue is founded in a mix of Silverlight, Asp.Net and WCF, basically if you’re doing multiple calls to a single WCF web-service and you have Asp.Net session state enabled, the calls will be executed sequentially by the service, hence any long running calls will block subsequent ones."
I am assuming that the blocking is only an issue if you are making multiple calls to the same service, and that two simultaneous calls to two different methods on two different services should not result in one blocking the other?
The suggested solution to the problem in SL3 involves using the following syntax in the Application_Startup method:
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
The session state will then have to be maintained on WCF calls by seting up a cookie container, and sharing it across all of your proxies (see http://forums.silverlight.net/forums/p/174322/393032.aspx)
Is this still the recommended solution in Silverlight 4? Has anyone used an alternative approach?
In .NET 4, you can do this in Application_BeginRequest
if (Context.Request.Path.EndsWith("xxx.svc"))
Context.SetSessionStateBehavior(SessionStateBehavior.Disabled);
If you are making a call into an ASP.Net application, and you are using session cookies, then all the calls into the application are serialized (apart from ones where the page explicitly opts out of session state).
Normally this isn't a big issue, because a client browser typically hits an ASP.Net page plus a bunch of resources (images, js, css etc...), and these latter aren't mapped to ASP.Net so IIS serves them up natively. But if you try and hit two ASP.Net pages at the same time (eg in a frameset) you will see them load up one after another.
Now I don't know that this happens with WCF, but based on what you say, if you see that behaviour for one service I would expect to see that for all of them, because the session is per-user, not per-service.
In ASP.Net you can 'opt out' of session state on a page by page basis. If that's possible for a hosted WCF service, and viable for your scenario (to make the services stateless) that would aleviate the issue. Or move one or more services to a different ASP.Net application (different session)
Bear in mind that you can see other issues here to do with the instancing and reentrancy models of the service. Your problem as described above is a per-user concurrency issue, but there are others. For example, if you set the service up as a singleton (InstanceContextMode.Single) and non-reentrant (ConcurrencyMode.Single) then only one request will ever be processed at a time across all users.
Update: Doing some doco reading:
WCF services aren't enrolled into ASP.Net sessions unless you ask for it (using )
WCF services can on a per service basis opt in, using the [AspNetCompatibilityRequirements] attribute on the service implementation
There doesn't seem to be any way of opting in but not opting into Session state.
There's a good blog post about this on Wenlong Dong's site
So from what I can see you should be able to use AspNetCompatibilityRequirementsMode.NotAllowed to opt out individual services completely from ASP.Net services. Alternatively, leave it off by default and only opt-in the ones that need access to the ASP.Net session (bearing in mind that unless you really need to share the same session with ASP.Net, just using WCF's session services is probably a better bet).
Is there any limitations on AJAX Calls with ScriptManager to Web Services?
I have an application and I need an AJAX enabled form in it. After every Insert or Delete, I have to get a list from database and show it on page. So I call two server methods from my JS.
Isn't too many AJAX calls gonna cause any errors(eg. timeouts, transfer errors etc.)?
Too many of any kind of request will give you the same things to worry about. An AJAX request is just like any other HTTP request, a ScriptManager control won't be imposing any constraints.
The only limitation is your hardware and your IIS settings (application pool connections, etc.).
Of course, you should always be smart about how you program your methods, utilize caching where appropriate, etc. to ensure that they will hold up under heavy load.