3

我问的原因是因为该HttpContext.Current.Items集合似乎是放置IDisposable对象的好地方,例如 aDataContext以便存储库可以透明地访问它,而不必将与特定 ORM 技术相关的任何依赖项注入到存储库中。这也将允许存储库决定是否参与UnitOfWork或承担实际持久化任何更改的额外责任。

例如:

这页纸:

protected void Page_Load(...)
{
   Items[KeyValueFromConfigurationFile] = new DataContext();
   var repo = new Repository();
   var rootEntity = repo.GetById(1);
}

存储库:

public virtual TEntity GetById(int id)
{
   var ctx = HttpContext.Current.Items[KeyValueFromConfigurationFile] as DataContext;
   return ctx.TEntities.SingleOrDefault(p => p.Id == id);
}

当然,如果集合DataContext中没有它,我会检查空值并执行获取 a 所需的步骤。HttpContext.Current.Items

所以,回到我最初的问题,给出上面的代码:即使抛出异常,它是否会与它的 Items 集合中包含的任何对象一起被处置?HttpContext.Current

4

2 回答 2

13

HttpContext.Current.Items 中的对象不会被自动释放。你需要自己处理这个。您可以在 global.asax Application_EndRequest 中执行此操作:

            foreach (var item in HttpContext.Current.Items.Values)
            {
                var disposableItem = item as IDisposable;

                if (disposableItem != null)
                {
                    disposableItem.Dispose();
                }
            }
于 2011-02-07T16:37:58.347 回答
2

我认为上一篇提供解决方案的帖子没有问题,因为基础集合没有被修改,在枚举时无法完成,但我最近确实遇到了这段代码的零星错误。我们看到错误“收藏已修改;当 OnEndRequest 触发并执行下面的 for 循环时,枚举操作可能不会执行:

        foreach (var item in HttpContext.Current.Items.Values)
        {
            var disposableItem = item as IDisposable;

            if (disposableItem != null)
            {
                disposableItem.Dispose();
            }
        }

因此,显然在使用 foreach 循环迭代集合的同时处理当前的 HttpContext 项也会造成问题。有几种方法可以解决这个问题,但我选择这样做:

        int size = HttpContext.Current.Items.Count;
        if (size > 0)
        {
            var keys = new object[size];
            HttpContext.Current.Items.Keys.CopyTo(keys, 0);

            for (int i = 0; i < size; i++)
            {
                var obj = HttpContext.Current.Items[keys[i]] as IDisposable;
                if (obj != null)
                    obj.Dispose();
            }
        }
于 2013-09-25T17:41:28.107 回答