实体框架的这种实现是否会泄漏内存?
我只是无法确定实体上下文在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个奇怪的设计。正如 @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.