下面的代码给我这个代码分析错误


  CA2000:Microsoft.Reliability:在方法'SessionSummary.SessionSummary_Load(object,EventArgs)'中,在对对象“实体”的所有引用均超出范围之前,调用System.IDisposable.Dispose。


我正在使用“正在使用”语句,因此对此感到惊讶:

    private void SessionSummary_Load(object sender, EventArgs e)
    {
        using (var entities = new DbEntities(Properties.Settings.Default.UserConnectionString))
        {
            entities.CommandTimeout = 7200;
            var sessions = from t in entities.TableName
                            where t.UserSession.Id == _id && t.Parent == 0
                            group t by new { t.UserSession, t.UserSession.SessionId } into sessionGroup
                            select new
                            {
                                Id = sessionGroup.Key.UserSession,
                                Session = sessionGroup.Key.SessionId
                            };

            summaryDataGridView.DataSource = sessions.Where(x => x.Time > 0.00);
            summaryDataGridView.Columns[4].DefaultCellStyle.Format = "N2";
            summaryDataGridView.Columns[4].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
        }
    }

最佳答案

实际上,您有一个潜在的过早处置方式,而不是较晚的处置方式,因为参与分配给数据源的闭包的实体意味着它离开了作用域。

然后,您将获得一个无法在其实际范围内处理的实体,这是分析所抱怨的,但是与在最后处理之前将其处理相比,这不太可能成为问题。用过的。

选项:


保持原状。如果上述方法有效,则可能是因为处置不会影响关闭起作用的必要状态。这是子。赌“可能”不是一个好主意,并且可能会改变未来。 (我可以想到一种情况,在处理后使用对象是有意义的,但这是晦涩的,无论如何,这不是您所拥有的)。
强制执行查询。在查询上调用ToList()ToArray()将对其运行,并创建一个内存中结果,然后将其用作数据源。充其量虽然在时间和空间上都效率较低。在更糟的情况下,它可能会令人崩溃(取决于您要处理的结果的大小)。
在离开范围之前,请确保控件使用其数据源完成操作。然后清除数据源。根据所涉及的控件和其他一些事项(尤其是如果它具有显式的DataBind()方法),它可能是微不足道的,不可能的,或者介于两者之间。
将实体放入实例变量。实现IDisposable。在您的Dispose()方法中,将其称为Dispose()方法。请勿为此添加终结器,因为您仅在布置托管对象。
创建一个可枚举的方法来包装查询(和用法),然后对查询返回的每个项目执行yield return。将此用作数据源。


对于大多数情况,5似乎是最好的选择。它的优点是在不增加代码2的同时不增加数字2的开销(可能会很大,具体取决于数据)的开销。请注意,仅调用AsEnumerable(对执行顺序的影响几乎相同)不会具有相同的效果。效果,因为关闭操作仍将使该块不执行。

编辑:包装查询的枚举将像:

private IEnumerable GetSessions()
{
    using (var entities = new DbEntities(Properties.Settings.Default.UserConnectionString))
    {
        entities.CommandTimeout = 7200;
        var sessions = from t in entities.TableName
                        where t.UserSession.Id == _id && t.Parent == 0
                        group t by new { t.UserSession, t.UserSession.SessionId } into sessionGroup
                        select new
                        {
                            Id = sessionGroup.Key.UserSession,
                            Session = sessionGroup.Key.SessionId
                        };

        foreach(var sess in sessions.Where(x => x.Time > 0.00))
          yield return sess;
    }
}


然后将更改SessionSummary_Load设置为:

private void SessionSummary_Load(object sender, EventArgs e)
{
        summaryDataGridView.DataSource = GetSessions();
        summaryDataGridView.Columns[4].DefaultCellStyle.Format = "N2";
        summaryDataGridView.Columns[4].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
    }
}


希望这可以解决问题,因为entities永远不会离开using的范围。

关于c# - CA2000错误,带有“using”语句。如何使其有效?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3622946/

10-10 14:45