Field members versus method variables?
I recently thought about the performance difference between class members and method variables. What I mean in the following example:
Let's say we have an object DataContext
for Linq2SQL
class DataLayer
{
ProductDataContext context = new ProductDataContext();
public IQueryable<Product> GetData()
{
return context.Where(t=>t.ProductId == 2);
}
}
In the above example, the context will be stored on the heap and the method variables GetData
will be removed from the Stack after the method is executed.
So, consider the following example to make the difference:
class DataLayer
{
public IQueryable<Product> GetData()
{
ProductDataContext context = new ProductDataContext();
return context.Where(t=>t.ProductId == 2);
}
}
(* 1) So, first of all, we know that if we define an instance ProductDataContext
as a field, we can reach it everywhere in the class, which means that we don't have to create the same instance object all the time.
But let's say we are talking about Asp.NET and as soon as users click the submit button, the post data is sent to the server and the events are executed and the published data is stored in the database using the above method, so there is a chance that the same is the same the user can send different data one after another. If I know correctly after the page is executed, the finalizers start playing and clearing things from memory (from the heap), which means that we lose our instance variables from memory, and also the post DataContext
needs to be re-created for a new page loop.
So it seems that the only benefit of publicly declaring this class for the entire class is text only one number above.
Or is there something else?
Thanks in advance...
(If I said something wrong, correct me ..)
a source to share
When it comes to the performance difference between creating an object by a method or an instance of a class, I wouldn't bother with that. However, what you seem to be missing here are important principles in the DataContext class and block of general work.
The DataContext class works as a whole. So you create a DataContext, you create objects, you update and delete objects, you submit all changes, and after that you delete the DataContext. You can create multiple DataContext classes for each request, one per (business) transaction. But in ASP.NET, you should never create a DataContext that survives a web request. All DataContexts created during a request must be removed when or before this request has completed. There are two reasons for this.
First of all, the DataContext has an internal cache of all the objects it fetched from the database. Using the DataContext for a long period of time will make its cache grow indefinitely and can cause memory problems when you have a large database. The DataContext will also facilitate returning an object from the cache when possible, which will quickly expire your objects. Any update and delete operation performed on another DataContext or directly on the database may go unnoticed due to this inaccuracy.
The second reason for not caching DataContexts is that they are not thread safe. It is best to see the DataContext as a unit of work or as a transaction (business). You create a bunch of new objects, add them to the DataContext, change some others, delete some objects, and when you do that, you call SubmitChanges. If another request calls SubmitChanges on the same instance during this operation, you lose the idea of a transaction. When you let your code do this, in the best possible case your new objects will be saved and your transaction will be split into two separate transactions. In the worst case, you leave your DataContext or the objects it keeps in an invalid state, which could mean other requests are failing or invalid data is entering your database.And this is not an unlikely scenario. I've seen strange things happen in projects, the developers have created a single (static) DataContext for each website.
So with that in mind, let's get back to your question. While defining the DataContext as an instance field is not a problem, it is important to know how you use the class DataLayer
. When you create one DataLayer
for each request or for a method call, you will probably be safe, but in this case, you should not store this DataLayer
in a static field. When you want to do this, you must create a DataContext call for each method.
It's important to know what class design is DataLayer
. In your code, you only show us the request method. There are no CUD methods. Does each method mean one transaction or do you want to call multiple methods and then call SaveChanges on DataLayer
? If you want the last parameter, you need to store DataContext
as an instance field, in which case you must implement IDisposable
on DataLayer
. When each method is its own transaction, you can create a DataContext for each method, and you must wrap the DataContext in a using statement. Note, however, that deleting the DataContext can cause problems when returning objects with lazy load properties from a method. These properties can no longer be loaded when the DataContext is placed. Here's more interesting information on this.
As you can see, I didn't even talk about which of your two options would be better for performance, because performance doesn't matter when the solution gives inconsistent and incorrect results.
I apologize for my long answer :-)
a source to share
You never want to store the DataContext class at the class level. If you do, you will need to implement the IDisposable interface in your class and call Dispose when you know you are done with it.
Better to just create a new DataContext method in your method and use with a statement to get rid of it automatically when you're done.
Although the implementation of IDisposable in the DataContext does nothing, this is an implementation detail, whereas displaying the IDisposable interface is a contract that you must always abide by.
This is especially handy if you are switching to LINQ-to-Entities and using the ObjectContext class , where you must call Dispose on the instance when you're done with it, otherwise resources will leak until the next garbage collection.
a source to share
So this is the only benefit to publicly declaring its class - it's only text number one above.
Yes, declaring a class-level variable should allow the entire class to access the same variable. It cannot be used to intentionally try to prevent garbage collection. Access modifier for properties, methods, etc. Used to determine which objects, external or internal to your class, can be accessed / modified / monkey by this piece of code.
In ASP.NET, when a request is sent to the browser, the objects generated for that page request will receive the CGed at some point in the future, regardless of whether this variable is public. If you want information to remain between requests, you need to create a single instance of the object, or serialize the object into session or application state.
a source to share
See this for example "Linq to SQL DataContext Lifetime Management": http://www.west-wind.com/weblog/posts/246222.aspx This approach makes life easier.
a source to share