实体框架的这种实现是否会泄漏内存?

发布于 2024-11-26 18:03:42 字数 3174 浏览 1 评论 0原文

我只是无法确定实体上下文在 Web 应用程序或控制台应用程序中的 using 语句中使用时是否已在使用流程中处理。

谢谢!

using System;
using System.Web;

namespace Foo.Model
{
    public partial class FooEntities : ObjectContext
    {
        private const string CurrentContextKey = "FooEntities.Current";

        [ThreadStatic]
        private static FooEntities _currentOnThreadStatic;
        private FooEntities _previousContext;

        /// <summary>
        /// Gets the current <see cref="FooEntities"/> instance, if an instance can be shared in the current context.
        /// </summary>
        /// <remarks>
        /// The current context is stored in the HTTP context, if it is available (otherwise it is stored in a thread-static instance).
        /// Multiple contexts can be stacked.
        /// </remarks>
        public static FooEntities Current
        {
            get
            {
                if (HttpContext.Current != null)
                {
                    return HttpContext.Current.Items[CurrentContextKey] as FooEntities;
                }
                else
                {
                    return _currentOnThreadStatic;
                }
            }

            private set
            {
                if (HttpContext.Current != null)
                {
                    HttpContext.Current.Items[CurrentContextKey] = value;
                }
                else
                {
                    _currentOnThreadStatic = value;
                }
            }
        }

        /// <summary>
        /// Returns a repository instance bound to this object context.
        /// </summary>
        /// <typeparam name="TRepository">The type of repository to instantiate.</typeparam>
        /// <returns>The repository instance.</returns>
        public TRepository GetRepository<TRepository>()
            where TRepository: BaseRepository
        {
            return (TRepository) Activator.CreateInstance(typeof(TRepository), this);
        }

        /// <summary>
        /// Ensures that an ambient context is available through <see cref="Current"/>, throwing an exception otherwise.
        /// </summary>
        /// <exception type="InvalidOperationException)">
        /// Thrown if <see cref="Current"/> is null.
        /// </exception>
        public static void EnsureContext()
        {
            if (Current == null)
            {
                throw new InvalidOperationException("An ambient FooEntities context is expected.");
            }
        }

        /// <summary>
        /// Releases the context instance.
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            Current = _previousContext;
            base.Dispose(disposing);
        }

        /// <summary>
        /// Is called by all constructors.
        /// </summary>
        partial void OnContextCreated()
        {
            _previousContext = Current;
            Current = this;
        }
    }
}

I just can't make out if the entity context is disposed in the usage flow when used in a using statement in a web application or a console application.

Thanks!

using System;
using System.Web;

namespace Foo.Model
{
    public partial class FooEntities : ObjectContext
    {
        private const string CurrentContextKey = "FooEntities.Current";

        [ThreadStatic]
        private static FooEntities _currentOnThreadStatic;
        private FooEntities _previousContext;

        /// <summary>
        /// Gets the current <see cref="FooEntities"/> instance, if an instance can be shared in the current context.
        /// </summary>
        /// <remarks>
        /// The current context is stored in the HTTP context, if it is available (otherwise it is stored in a thread-static instance).
        /// Multiple contexts can be stacked.
        /// </remarks>
        public static FooEntities Current
        {
            get
            {
                if (HttpContext.Current != null)
                {
                    return HttpContext.Current.Items[CurrentContextKey] as FooEntities;
                }
                else
                {
                    return _currentOnThreadStatic;
                }
            }

            private set
            {
                if (HttpContext.Current != null)
                {
                    HttpContext.Current.Items[CurrentContextKey] = value;
                }
                else
                {
                    _currentOnThreadStatic = value;
                }
            }
        }

        /// <summary>
        /// Returns a repository instance bound to this object context.
        /// </summary>
        /// <typeparam name="TRepository">The type of repository to instantiate.</typeparam>
        /// <returns>The repository instance.</returns>
        public TRepository GetRepository<TRepository>()
            where TRepository: BaseRepository
        {
            return (TRepository) Activator.CreateInstance(typeof(TRepository), this);
        }

        /// <summary>
        /// Ensures that an ambient context is available through <see cref="Current"/>, throwing an exception otherwise.
        /// </summary>
        /// <exception type="InvalidOperationException)">
        /// Thrown if <see cref="Current"/> is null.
        /// </exception>
        public static void EnsureContext()
        {
            if (Current == null)
            {
                throw new InvalidOperationException("An ambient FooEntities context is expected.");
            }
        }

        /// <summary>
        /// Releases the context instance.
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            Current = _previousContext;
            base.Dispose(disposing);
        }

        /// <summary>
        /// Is called by all constructors.
        /// </summary>
        partial void OnContextCreated()
        {
            _previousContext = Current;
            Current = this;
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

左岸枫 2024-12-03 18:03:42

这是一个奇怪的设计。正如 @Joel C 在他的评论中指出的那样,您应该将对象上下文视为一个短暂的对象,您在需要时创建它并在之后立即释放。

但我认为这没有理由会泄漏内存。您只处理托管资源,并且始终对 HttpContext 使用相同的密钥,因此您不会一直创建新对象。

It is an odd design. As @Joel C points out in his comment you should regard the object context as a shortlived object that you create when you need it and release right afterwards.

But I see no reason that this would leak memory. You are only dealing with managed resources and you are using the same key all the time to the HttpContext so you won't create new objects all over.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文