即使抛出异常,HttpContext.Current也会被处理掉吗?

时间:2009-07-18 16:47:35

标签: c# linq-to-sql repository-pattern datacontext idisposable

我问的原因是因为HttpContext.Current.Items集合似乎是放置IDisposable对象(例如DataContext)的好地方,以便存储库可以透明地访问它而不需要将与特定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集合中没有HttpContext.Current.Items,我会检查空值并执行获取HttpContext.Current所需的步骤。

所以,回到我给出上述代码的原始问题:即使抛出异常,{{1}}是否会与其Items集合中包含的任何对象一起处理? < / p>

2 个答案:

答案 0 :(得分: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();
                }
            }

答案 1 :(得分: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();
            }
        }