2011-08-22 38 views
1

我一直在试图找出我们的ASP.NET Web应用程序的一些性能问题。这是一个在线应用程序,由多个用户使用(10+)。只是一个快速的概述:应用程序使用Web表单,MVC页面,Web服务等的组合......当多个用户连接到应用程序,它似乎变得非常慢。在调查了内存之后,似乎应用程序正在使用大量内存,并且正在减慢计算机的速度,这表明未处理的资源未被处理。我安装了ANTS,然后在系统上捕获了几个应用程序。原来很多内存被非托管资源使用:http://tinypic.com/r/154ujra/7ASP.NET WebApp性能问题:如何解决?

这是我第一次分析内存。 ANTS分析器表明我的一个类(RULE)具有大量活动实例:http://tinypic.com/r/1264ltu/7(似乎没有被GC释放)

在钻入级别级别http://tinypic.com/r/2r3v6nq/7后,它显示一个警告类没有从内存中释放,这可能是因为事件处理程序未被注销。既然这个类包含一个事件处理程序实例,那么它可能是那样吗?然后

public class Rule 
{ 
    public event EventHandler deleted; 

    public void Delete() 
    { 
     if (baseQuestionnaire.basePortfolio.mode != Mode.Admin) 
     { 
      throw new Exception("Rules can only be deleted in Admin mode"); 
     } 
     else 
     { 
      // Delete the rule from the database 
      if (id != -1) 
      { 
       string delete = "DELETE FROM tb" + DataManager.dbPrefix + "_QuestionRule WHERE QuestionRuleId = " + id.ToString(); 
       DataManager.execute(delete); 
      } 

      // Raise a deleted event 
      if (deleted != null) 
       deleted(this, new EventArgs()); 
     } 
    } 
} 

事件被分配在这样的另一个类,但从来未注册

public class Option : IComparable 
{ 

    public void AddRule(Rule newRule) 
    { 
     newRule.deleted += new EventHandler(newRule_deleted); 
     allRules.Add(newRule); 
    } 

    ............................ 
} 
+0

什么是DataManager的?你也可以显示那个代码吗? –

+0

DataManager是一个密封的静态类,包含经常使用的数据库方法和包装器,就像上面的execute方法是cmd.ExecuteNonQuery()的简单包装器一样。 – FaNIX

回答

1

嗯..我看到了事件处理程序“已删除”是公共的。所以我的猜测是Rule对象是先创建的,然后Rule.deleted被分配了一个事件处理器。如果是这种情况,那么正如你怀疑的那样,事件处理程序可能是规则对象未被垃圾收集的原因。

编辑:

也许你可以尝试这样的事:

public class Option : IComparable, IDisposable 
{ 

    private Rule newRule; 
    private EventHandler newRuleDeletedEventHandler; 

    public void AddRule(Rule newRule) 
    { 
     this.newRule = newRule; 
     newRuleDeletedEventHandler = new EventHandler(newRule_deleted); 
     newRule.deleted += newRuleDeletedEventHandler; 
     allRules.Add(newRule); 
    } 

    public override void dispose() 
    { 
     newRule.deleted -= newRuleDeletedEventHandler; 
    } 
} 
+0

我更新了线程。该事件在另一个名为Option的类中分配。我只是不确定何时以及如何取消注册该事件。 – FaNIX

+0

是的,这是我的想法。我是否需要在任何时候明确地在规则对象上调用dispose方法,还是需要执行上述所有操作?我还实现了Finalize方法,该方法调用dispose方法,以防对象未被处置或对其引用丢失。 – FaNIX

+0

您可能不需要在Rule类中做任何事情 - 因为它是对Rule类的引用正在产生问题,并且此时我们怀疑Option是罪魁祸首。 Finalize可能会有所帮助,事实上,您可以重构此操作以在Finalize of Options本身中取消注册事件,而不是处置。那么,在此之后你看到有什么不同?或者我们在咆哮错误的树? –