字段成员VS方法变量? [英] Field Members vs Method Variables?

查看:131
本文介绍了字段成员VS方法变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我一直在思考类字段成员和方法变量之间的性能差异。正是我的意思是在下面的例子:

Recently I've been thinking about performance difference between class field members and method variables. What exactly I mean is in the example below :

假设我们有一个的DataContext 对象的 LINQ2SQL

Lets say we have a DataContext object for Linq2SQL

class DataLayer
{
    ProductDataContext context = new ProductDataContext();

    public IQueryable<Product> GetData()
    {
       return context.Where(t=>t.ProductId == 2);
    }
}

在上面的例子中,上下文将被保存在堆和的GetData 方法变量将从堆栈方法被执行后会被删除。

In the example above, context will be stored in heap and the GetData method variables will be removed from Stack after Method is executed.

所以,让我们考察下面的例子来作区分:

So lets examine the following example to make a distinction :

class DataLayer
{
    public IQueryable<Product> GetData()
    {
       ProductDataContext context = new ProductDataContext();
       return context.Where(t=>t.ProductId == 2);
    }
} 

(* 1):我们知道这样行不行第一件事情是,如果我们定义 ProductDataContext 实例作为一个领域,我们可以无处不在的达到它一流的,这意味着我们不必创建同一个对象实例的所有时间。

(*1) So okay first thing we know is if we define ProductDataContext instance as a field, we can reach it everywhere in the class which means we don't have to create same object instance all the time.

但可以说我们正在谈论Asp.NET一旦用户preSS提交按钮后的数据发送到服务器和事件执行,并存储在通过该方法的数据库发布的数据上面,因此很可能,同样的用户可以发送不同的数据后的一个another.If我知道正确执行页面后,将终结发挥作用,明确的东西从内存(从堆),这意味着我们失去从内存中我们的实例变量,以及又经过后,的DataContext 应为新的页面周期再次创造。

But lets say we are talking about Asp.NET and once the users press submit button the post data is sent to the server and the events are executed and the posted data stored in a database via the method above so it is probable that the same user can send different data after one another.If I know correctly after the page is executed, the finalizers come into play and clear things from memory (from heap) and that means we lose our instance variables from memory as well and after another post, DataContext should be created once again for the new page cycle.

因此​​,似乎公开宣称它全班唯一的好处是上面的数字只是一个文本。

So it seems the only benefit of declaring it publicly to the whole class is the just number one text above.

或者是有其他的东西吗?

Or is there something other?

在此先感谢...

(如果我告诉一些不正确,请修复我..)

(If I told something incorrect please fix me.. )

推荐答案

当谈到创建每个方法或每类实例对象之间的性能差异,我不会担心得多了。但是,你似乎在这里错过了什么都是围绕着DataContext类的一些重要原则和一般。

When it comes to the performance difference between creating an object per method or per class instance, I wouldn't worry to much about it. However, what you seem to miss here are some important principles around the DataContext class and the unit of work pattern in general.

DataContext类为单个工作单位运行。因此,您可以创建一个DataContext,您创建,更新和删除对象,您提交的所有更改,你以后处置的DataContext。你可能每个请求创建多个的DataContext类,每(业务)交易之一。但在ASP.NET你不应该创建一个幸存Web请求一个DataContext。何时或在此之前的要求是在被请求过程中创建的所有DataContexts应释放。有两个原因。

The DataContext class operates as a single unit of work. Thus, you create a DataContext, you create objects, update and delete objects, you submit all changes and you dispose the DataContext after that. You may create multiple DataContext classes per request, one per (business) transaction. But in ASP.NET you should never create a DataContext that survives a web request. All the DataContexts that are created during a request should be disposed when or before that request is over. There are two reasons for this.

首先,在DataContext具有它从数据库中读取的所有对象的内部缓存。使用一个DataContext为很长一段时间将其缓存无限增长,并可能导致内存问题,当你有一个大的数据库。在DataContext也将有利于时候才可以,让你的对象很快去陈旧从缓存中返回一个对象。在另一个DataContext的,或直接对数据库所做的任何更新和删除操作可能因为这个过时的获得被忽视。

First of all, the DataContext has an internal cache of all objects that it has fetched from the database. Using a DataContext for a long period of time will make its cache grow indefinitely and can cause memory problems when you’ve got a big database. The DataContext will also favor returning an object from cache when it can, making your objects go stale quickly. Any update and delete operation made on another DataContext or directly to the database can get unnoticed because of this staleness.

第二个原因不缓存DataContexts是,他们不是线程安全的。这是最好看的一个DataContext作为一个工作单元,或作为一个(业务)交易。您创建一个新的一堆对象,将它们添加到DataContext,改变一些人,删除一些对象,当你做,你打电话的SubmitChanges。如果在运行过​​程中另一个请求调用同一实例的SubmitChanges,你失去了交易的念头。当你让code要做到这一点,最幸运的情况下,新的对象将是持久和您的交易是在两个不同的交易拆分。在最坏的情况,您离开您的DataContext,或处于无效状态持续存在的对象,这可能意味着其他请求失败或无效的数据进入数据库。这是没有不可能的情况,我已经看到了奇怪的事情发生在项目被开发人员创建的每个网站的单一(静态)的DataContext。

Second reason for not caching DataContexts, is that they are not thread-safe. It’s best to see a DataContext as a unit of work, or as a (business) transaction. You create a bunch of new objects, add them to the DataContext, change some others, remove some objects and when you’re done, you call SubmitChanges. If another request calls SubmitChanges on that same instance during that operation, you are losing the idea of the transaction. When you are allowing code to do this, in the most fortunate situation, your new objects will be persisted and your transaction is split up in two separate transactions. At worst, you leave your DataContext, or the objects it persists in an invalid state, which could mean other requests fail or invalid data enters your database. And this is no unlikely scenario, I’ve seen strange things happen on projects were developers created a single (static) DataContext per web site.

所以考虑到这一点,让我们回到你的问题。当定义一个DataContext的实例字段不是问题,重要的是要知道你是如何使用数据层类。当你有一个数据层每个请求或每方法调用创建,你可能是安全的,但在这种情况下,你不应该存储数据层在静态字段。当你想这样做,你应该创建每个方法调用一个DataContext。

So with this in mind, let’s get back to your question. While defining a DataContext as instance field is not a problem, it is important to know how you are using the DataLayer class. When you create one DataLayer per request or on per method call, you’ll probably be safe, but in that case you shouldn’t store that DataLayer in a static field. When you want to do that, you should create a DataContext per method call.

知道数据层类的设计是什么是很重要的。在您的code你只告诉我们一个查询方法。没有CUD方法。是每一个方法的意思是一个单一的交易,或者你想调用多种方法和呼吁数据层事后的SaveChanges?当你想要这个最后的选择,你需要存储的的DataContext 为实例字段,你应该实现这种情况下,的IDisposable 数据层。当每一个方法是它自己的事务,可以为每个方法的DataContext的,你应该在using语句包裹一个DataContext。但是请注意,当你从一个方法延迟加载属性返回对象处理DataContext的可能会导致问题。这些属性可以在DataContext设置时不能再加载。 <一href=\"http://stackoverflow.com/questions/2785506/linq-to-sql-web-application-best-practices/2786713#2786713\">Here大约是这更有趣的信息。

It is important to know what the design of the DataLayer class is. In your code you only show us a query method. No CUD methods. Is every method meant to be a single transaction, or do you want to call multiple methods and call a SaveChanges on the DataLayer afterwards? When you want this last option, you need to store the DataContext as an instance field and in that case you should implement IDisposable on the DataLayer. When every method is its own transaction, you can create a DataContext per method and you should wrap a DataContext in a using statement. Note however, that disposing the DataContext can cause problems when you return objects with lazy loading properties from a method. Those properties cannot be loaded anymore when the DataContext is disposed. Here is more interesting information about this.

正如你所见,我还没有谈过,其中的两个选项将是更好的性能,因为性能并不重要,当解决方案提供了不一致的,不正确的结果。

As you see, I haven’t even talked about which of your two options would be better for performance, because performance is of no importance when the solution gives inconsistent and incorrect results.

我为我的长不好意思的回答: - )

I'm sorry for my long answer :-)

这篇关于字段成员VS方法变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆