I have a web application developed in .net 2.0
I am storing large business objects in session, which change frequently.
Some times I observe server error. Is this causing the error?
Is there any alternative way to store these objects?
Thanks in advance
Rather than storing business objects in session you would be better of with an architecture that allows you to store the data in a database, and cache data for an appropriate period of time.
Your current architecture using session will ultimately have scaling issues unless you store the session data in a database, so, you might as well get the data from the database in the first place.
Store the data in a database on a user by user basis.
EDIT
Cache the results if you are wanting to read every 5 seconds.
Might not be the solution though.
Based on the data you've provided, it doesn't seem like the issue is performance related.
On the "Object reference not set error". It seems to me that there is a thread synchronization issue. The session object is retrieved and used while/before you are trying to set the session object(s) to the value from your service call. You could add thread synchronization(ReaderWriterLock?) to see if that minimizes the error.
Related
This application is running in a load balanced environment. It uses a SQL database as the session store. The app is simple and does not have it's own database.
I have created an endpoint to be called from another internal server that knows the SessionId. I want this endpoint to be able to grab a session variable by SessionId instead of from the current session.
I know that I could create a new database to do this, but it would be overkill as it would only have 1 table with 2 fields, SessionId and the one value related to it. I could even put this table in the current session database. I am trying to avoid having to add database connection code if at all possible.
Is there a way to access the variables of a different session other than the current session?
I might be wrong and if I am - downvote; the fact that the session state storage is database-based (and not in-memory) does not change the principles of how the IHttpSessionState works. I doubt you will be able to do that and I doubt you actually want to: you simply cannot access an absolutely separate context from a different context. Doing so has a lot of potential issues (thread safety, problems if the session state implementation is changed and so on). Your web application might not be aware of the session state store.
For example, if I simply use session state and have the session state configured directly in IIS, there is no way for the application thread to know it's in the database which immediately presents an issue: what if I decide to run the same application without the DB-backed session state? No changes to application code are required, just IIS reconfiguration. It might introduce unexpected behavior and/or runtime errors.
The suggestion (in the comment) to set the cookie to the known session ID is the only "way out" but from the security perspective it's less than optimal.
However, what you are trying to implement seems like a proper job for a Cache Provider. You can use SqlCacheDependency from System.Web.Caching to use the database for your cache. Then you could use the aforementioned SessionId as one of the cache identifiers.
In my ASP.NET-MVC-application I store information in static classes with static vars. But ASP.NET is recycling all data and threads after and my "App_Start"-procedure will call after the cleanup.
I solved the problem with the backup-tasks with HangFire.
But to generate the static-class, I need a long time. The first request after the recycle has to wait while the static-classes are set up.
Why the delay? I am using the EntityFramework and for correct handling I need all records from the database with their relations.
So I hold all records with static-classes and use the database as 2nd strategy.
I have no ideas what I can do to improve performance.
My first idea was to serialize the complete data - but how is the performance for deserialize a ArrayList with 2K or more records?
Is there a way to prevent the recyclefor my static ArrayList?
I'd recommend you use the application cache mechanism for ASP.NET instead. However, by default, the cache is still in-memory and maintained within the process, so app pool recycles would still wipe it out. The solution is to change the storage location of the application cache so it's in a different process. See this answer for some recommendations for how to store your application cache.
In short, I wouldn't recommend trying to avoid app pool recycling since it can really save you a lot of trouble.
I am working on a maintenance of one asp.net application where I found pervious developers have implemented data caching as like a session, means they stored data in a cache for per session like this
Public Function GetDataCache(ByVal dataCacheKey As String) As Object
dataCacheKey = dataCacheKey & Convert.ToString(LoginSessionDO.UserID)
Return Cache(dataCacheKey)
End Function
In this application there are many screens where user can add multiple rows (data) in a grid temporary which actually store in cache for that particular current user only and finally press save button to save data in database.
My question is if caching is used like a session! will it give any performance improvement?
actually I can change it in my dev. environment to check performance but we cannot create load like prod in our environment and also without any surety I cannot change and deploy code in production.
Please suggest me
Is caching is good the way its implemented?.
It’s using like a session would it have better performance than session?
The cache will need to be cleared out, otherwise all items will remain until the app domain recycles. Session has a much shorter expiry and can be explicitly abandoned on log out, for example.
This might be a scaling issue if your site grows. However, the shorter expiry time of the session might cause you issues with saving if it is no longer there when expected. A staging table in the db might be a better approach.
An edit from several years after the initial answer.
In reality, it would be much preferable to store the added rows on the client side and then submit them all in one go. Either of the server side options above run into issues if the app domain recycles in the middle of a session and both will cause you scaling issues on the server with enough users/data.
I have a controller that needs to persist the state of a Dictionary member. On navigating to a specific action, an entry for that user is created and added to the dictionary. I require a separate ajax action to pull the object out, use it, and save it back, however it seems as though between the two events my dictionary is being collected.
Now I've tried a number of things to ensure that this dictionary stays put but to no avail. As a requirement, I need this dictionary to stay resident in memory for quick access. I understand that MVC is supposed to be stateless and I should use a different kind of backing store. Suggestions?
From your description putting the dictionary into the Session should be an option. The session store has the following properties:
Stays alive between requests.
Complete separation of different uses/sessions.
Easy to set up - no database or file to configure.
Quick access since it is normally handled in memory.
Not suitable for large amounts of data.
The session store is cleared if the application pool is recycled (which happends sometimes).
There are many backing stores available:
Session
Files
Database
...
Up to you to pick one.
I understand that storing DataTable in session variable in asp.net is bad since it will use a lot of server's memory. What I don't understand is that then what do you do when:
User comes to a page where it requires to load a DataTable object (from SQL Server).
User clicks on radio button for simple event (Ex. some controls get disabled).
If you don't save the DataTable object in the session, you have to load it from the SQL server again upon postback on same page instead of just fetching it from the session?
Thanks for help.
DataTable's are pretty heavy objects and are not recommended to be stored in ViewState or Session for that matter. The scenario you describe is about caching data. So, why not use ASP.NET's cache?
ViewState, while it does not use as much memory on the server as Session or Cache, still requires serialization/deserialization on the server, requiring some temporary memory usage, in addition to providing your users a large payload of data on each request to/from the server (just take a peek at View Source in any browser and you'll see a very large hidden input with base-64 encoded data). If you don't use encryption, anyone can decode that data being delivered in each request, causing a potential security problem if any of that data is sensitive. ViewState is also meant for small amounts of data and is usually best to stick to the primary data types like ints and strings.
Session generally isn't a good idea either as it also requires serialization/deserialization, which adds additional overhead in addition to the strain on memory per user. Session has memory limits that decrease per user as you increase concurrent users. Session data does not "expire" until the actual session expires for each user, which by default is 30 minutes. Session is great for user-specific data, but is recommended to keep very small and again stick to the primary data types like ints and strings.
Cache does not serialize any data and is limited in size only due to the bitness of the OS. On Windows 2003 32-bit, you have 800 MB total application pool size to work with (1.2 or 1.3 GB if you use the /3GB switch). Under 64-bit, there's much more freedom and limitations are realistically only what you configure up to the amount of available system memory. A benefit of cache is that as memory pressure increases, cache can be expired to free memory for more important things. You also have control as to when items get expired when memory pressure isn't a factor (expiry's are not guaranteed). Take an additional step and you can put a cache dependency on data in the database, if using SQL Server, allowing the data itself to decide when to expire your cache, ensuring fresh data.
Lastly, the often forgotten about Application object can be used, but only for data that you know can be shared across users and does not need to change that often (hopefully not until an application restart).
Use Microsoft's documentation for ViewState, Session, Cache, and Application objects, to determine the wisest use of each for your particular scenario. A combination of using these correctly in addition to using AJAX (to avoid full page postbacks) and HTTP compression to reduce the payload delivered to the client can make for a very responsive site.
In more complex scenarios like Web farms and load balancing, there are additional issues to think about. Questions you will need to ask yourself will be things like: Should a new session be created if a user hits a different server than the originally requested one? Should cache work no matter what server a user hits? These questions will bring you to solutions that may change where you store data. InProc Session is more forgiving than using, say SQL Server, as a session server, as there are additional serialization restrictions.
Another way to store the DataTable, if you only want to use it at page level, is in ViewState. ViewState["dtbl"] = DataTable;
And you can access it from the ViewState Simply DataTable dtbl = (DataTable)ViewState["dtbl"];