Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
遗留项目中C#代码可能存在的性能问题_C#_.net_Performance_.net 3.5_Processing Efficiency - Fatal编程技术网

遗留项目中C#代码可能存在的性能问题

遗留项目中C#代码可能存在的性能问题,c#,.net,performance,.net-3.5,processing-efficiency,C#,.net,Performance,.net 3.5,Processing Efficiency,我最近开始在一个新项目中工作,我们有数千行遗留代码。我们面临几个性能问题。我决定看一下代码,看到了以下内容。有一门课: public class BaseDataAccess { private Database dB; public Database DB { get { if (dB == null) { dB = DatabaseFactory.Crea

我最近开始在一个新项目中工作,我们有数千行遗留代码。我们面临几个性能问题。我决定看一下代码,看到了以下内容。有一门课:

public class BaseDataAccess
{
    private Database dB;

    public Database DB
    {
        get
        {
            if (dB == null)
            {
                dB = DatabaseFactory.CreateDatabase();
            }
            return dB;
        }
    }
}
以及许多继承自前一个基类的子类。在内部,这些其他类使用DB属性,如下所示:

DataSet ds = DB.ExecuteDataSet(spGetCustomersSortedByAge);
最后,还有一个巨大的类(5000行代码),包含数十种方法,如下所示:

public void ProcessPayments()
    {
        try
        {
            List<Employee> employees = new EmployeesDA().SelectAll(null);
            foreach (Employee employee in employees)
            {

                employee.Account = new MovementsDA().SelectAll(employee.Id, DateTime.Now);

                ...

                City city = new CitiesDA().Select(zone.cityId);

                ...

                Management m = new ManagmentDA().Select(city.id);

            }
        }
        catch (Exception ex)
        {
                ...
        }

    }
public void ProcessPayments()
{
尝试
{
List employees=new EmployeesDA()。选择全部(空);
foreach(员工中的员工)
{
employee.Account=newmovementsda().SelectAll(employee.Id,DateTime.Now);
...
城市=新城市数据()。选择(zone.cityId);
...
管理m=新建管理数据()。选择(city.id);
}
}
捕获(例外情况除外)
{
...
}
}
注意在前面的方法中,EmployeesDA、MovementsDA、CitiesDA和ManagementDA都是BaseDataAccess的继承者,在内部使用各自的DB属性。还要注意的是,它们经常在foreach循环中被实例化(在两个嵌套级别中多次)

我认为实例化本身是可疑的,但我更关心的是这里的数据库连接发生了什么?是否每个DA实例化后都会打开一个新的底层连接?这个代码有多糟糕


作为我考虑的解决方案的一个附带说明,如果这段代码应该被修复:我考虑将每个构造函数都设置为私有的,这样编译器开始抱怨实例化,并通过调用GetInstance方法重构实例化(singleton模式)避免重新创建对象和底层连接。但是,我不确定这是否在某种程度上也是危险的,例如,如果连接可能被关闭。当前的代码没有这个问题,因为实例化一直在发生。

通常错误地认为对象构造是昂贵的。它比基本算法或其他机器级别的东西要昂贵得多,但不可能是性能问题的直接来源

例如,在循环中使用装箱整数是浪费的,但是在每个循环中构造一个Employee对象与重用一个可变Employee对象相比,并不会带来有意义的性能优势

许多垃圾收集器能够在这样的循环中重用对象内存帧。实际上,在循环的每个过程中分配并覆盖一个对象帧


在这种特定情况下,如果DA具有显著的初始化成本,则可能会产生成本。如果是这样的话,我会重构代码,在循环之外创建这些代码。我不会使用实际的静态单例。如果需要,我会使用依赖项注入来管理单例对象。静态单例是有效的全局变量,是有状态耦合和模块化分解的邀请。

通常错误地认为对象构造是昂贵的。它比基本算法或其他机器级别的东西要昂贵得多,但不可能是性能问题的直接来源

例如,在循环中使用装箱整数是浪费的,但是在每个循环中构造一个Employee对象与重用一个可变Employee对象相比,并不会带来有意义的性能优势

许多垃圾收集器能够在这样的循环中重用对象内存帧。实际上,在循环的每个过程中分配并覆盖一个对象帧


在这种特定情况下,如果DA具有显著的初始化成本,则可能会产生成本。如果是这样的话,我会重构代码,在循环之外创建这些代码。我不会使用实际的静态单例。如果需要,我会使用依赖项注入来管理单例对象。静态单例是有效的全局变量,是对有状态耦合和模块化分解的邀请。

这种方法有很多错误,但是如果
DatabaseFactory.CreateDatabase()方法为每个调用返回一个新的、已连接的数据库连接,那么您就有一个很大的连接问题。另一个问题是事务支持。
ProcessPayments
不应该确保所有事情都发生在一次交易中吗?或者每个员工至少有一个事务,或者类似的事情?正确的处理方法是开始让程序中的连接状态可见,这样就必须对其进行管理。@LasseV.Karlsen,DatabaseFactory是一个.NET类,但我不确定每次CreateDatabase执行时都会发生什么。所以我希望有人能在这里解释一下。如果这里的数据库对象只是在执行查询时打开连接,然后关闭连接,对于许多开放的连接,您应该没有问题,但是您仍然应该考虑事务的问题。这种方法有很多问题,但是如果<代码>数据库工厂。代码>方法为每个调用返回一个新的、已连接的数据库连接,那么您就有一个很大的连接问题。另一个问题是事务支持。
ProcessPayments
不应该确保所有事情都发生在一次交易中吗?或者每个员工至少有一个事务,或者类似的事情?正确的处理方法是开始让程序中的连接状态可见,这样就必须对其进行管理。@LasseV.Karlsen,DatabaseFactory是一个.NET类,但我不确定每次CreateDatabase执行时都会发生什么。因此,我希望有人能给我们一些启示。如果这里的数据库对象只是在执行q时打开连接