gpt4 book ai didi

c# - CA2000 错误,语句为 'using'。如何使这个有效?

转载 作者:太空宇宙 更新时间:2023-11-03 18:46:50 25 4
gpt4 key购买 nike

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

CA2000 : Microsoft.Reliability : In method 'SessionSummary.SessionSummary_Load(object, EventArgs)', call System.IDisposable.Dispose on object 'entities' before all references to it are out of scope.

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

    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;
}
}

最佳答案

您实际上得到了一个潜在的过早处置,而不是一个迟到的处置,因为参与分配给数据源的闭包意味着它离开了范围。

然后在野外得到了一个不会在其实际范围内处置的实体,这是分析所提示的,但与它在最后一次使用之前就被丢弃了。

选项:

  1. 保持原样。如果上述方法有效,那么它可能是因为处置不会影响闭包正常工作的必要状态。这是冒险的。押注“可能”不是一个好主意,并且也可能在未来发生变化。 (我能想到一种情况,在处理后使用对象是有意义的,但它是模糊的,而且无论如何也不是你在这里拥有的)。

  2. 强制查询立即执行。在查询上调用 ToList()ToArray() 将运行它并创建一个内存结果,然后将其用作数据源。充其量,这在空间和时间上都会降低效率。更糟糕的是,它可能会非常严重(取决于您要处理的结果的大小)。

  3. 确保控件在离开范围之前完成使用其数据源。然后清除数据源。根据所讨论的控件和其他一些事项(特别是,如果它具有显式 DataBind() 方法),执行此操作可能微不足道、不可能或介于两者之间。

  4. 将实体放入一个实例变量中。实现 IDisposable。在您的 Dispose() 方法中,调用它的 Dispose() 方法。不要为此添加终结器,因为您只是在处理托管对象。

  5. 创建一个包装查询(和使用)的可枚举方法,然后对查询返回的每个项目执行 yield return。使用它作为数据源。

5 似乎是大多数情况下的最佳选择。它的优点是不会对代码进行太多更改,同时不会添加数字 2 的(可能很大,具体取决于数据)开销。请注意,只需调用 AsEnumerable(几乎对执行顺序有相同的影响)不会产生相同的效果,因为闭包仍然会使 block 未执行。

编辑:包装查询的可枚举如下:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com