我有以下代码
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
Run Code Online (Sandbox Code Playgroud)
dispose()
在using
语句括号结束时调用该方法}
对吗?由于我 return
在using
声明结束之前,MemoryStream
对象是否会被妥善处理?这里发生了什么?
是否有方法或其他轻量级方法来检查引用是否属于被处置对象?
PS - 这只是一种好奇心(睡得好,不在生产代码中).是的,我知道我可以ObjectDisposedException
试图访问该对象的成员.
我正在对我的一个较大的MVC应用程序进行重大的重构/速度调整.它已经部署到生产几个月了,我开始等待连接池中的连接超时.我已将问题跟踪到未正确处理的连接.
鉴于此,我已经对我的基本控制器进行了此更改:
public class MyBaseController : Controller
{
private ConfigurationManager configManager; // Manages the data context.
public MyBaseController()
{
configManager = new ConfigurationManager();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (this.configManager != null)
{
this.configManager.Dispose();
this.configManager = null;
}
}
base.Dispose(disposing);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我有两个问题:
configManager
管理DataContext
将IQueryable<>
参数公开给视图,我需要确保Dispose()
在视图完成渲染之前不会在控制器上调用.Dispose()
呈现视图之前或之后调用Controller?或者,MVC框架是否将其留给了GarbageCollector?我最近与同事讨论了Dispose
实施的价值和类型IDisposable
.
我认为即使没有非托管资源可以清理IDisposable
,也应该尽快清理类型.
我的同事有不同的想法; 执行IDisposable
,如果你没有任何非托管资源为你的类型,最终会被垃圾收集是没有必要的.
我的论点是,如果你有一个想要尽快关闭的ADO.NET连接,那么实现IDisposable
并且using new MyThingWithAConnection()
有意义.我的同事回答说,在封面下,ADO.NET连接是一种非托管资源.我对他回复的答复是,最终所有东西都是一种非托管资源.
我知道推荐的一次性模式,如果Dispose
被调用,你可以免费使用托管和非托管资源,但是如果通过终结器/析构函数调用,则只有免费的非托管资源(前面有关于如何提醒消费者不正确使用您的IDisposable类型的博客)
所以,我的问题是,如果你有一个不包含非托管资源的类型,是否值得实现IDisposable
?
注意这不是关于如何在C#中实现或模拟duck typing的问题...
几年来,我的印象是某些C#语言特性对语言本身定义的数据结构感到沮丧(这对我来说似乎总是一个奇怪的鸡蛋和鸡蛋场景).例如,我的印象是foreach
循环只能用于实现的类型IEnumerable
.
从那时起,我开始明白C#编译器使用duck typing来确定是否可以在foreach循环中使用对象,GetEnumerator
而不是查找方法IEnumerable
.这很有意义,因为它消除了鸡蛋和鸡蛋的难题.
我有点困惑,为什么这不是using
块的情况似乎并非如此IDisposable
.是否有任何特殊原因编译器不能使用duck typing并查找Dispose
方法?造成这种不一致的原因是什么?
或许还有其他东西在IDisposable的引擎盖下进行?
讨论为什么你会永远有未实现IDisposable是这个问题的范围之外的Dispose方法的对象:)
什么时候应该DbContext.dispose()
用实体框架调用?
这种想象的方法难道不好吗?
public static string GetName(string userId)
{
var context = new DomainDbContext();
var userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
context.Dispose();
return userName;
}
Run Code Online (Sandbox Code Playgroud)这是否更好?
public static string GetName(string userId)
{
string userName;
using(var context = new DomainDbContext()) {
userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
context.Dispose();
}
return userName;
}
Run Code Online (Sandbox Code Playgroud)这是否更好,也就是说,当使用using()时,是否应该调用context.Dispose()?
public static string GetName(string userId)
{
string userName;
using(var context = new DomainDbContext()) {
userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
}
return userName;
}
Run Code Online (Sandbox Code Playgroud)在C#中,如果某个类(如经理类)没有资源,那么拥有它有什么好处: IDisposable
吗?
简单的例子:
public interface IBoxManager
{
int addBox(Box b);
}
public class BoxManager : IBoxManager
{
public int addBox(Box b)
{
using(dataContext db = new dataContext()){
db.Boxes.add(b);
db.SaveChanges();
}
return b.id;
}
}
Run Code Online (Sandbox Code Playgroud)
使用BoxManager时,如果它还实现了IDisposable,那么内存使用会有什么好处吗? public class BoxManager : IBoxManager , IDisposable
例如:
BoxManager bm = new BoxManager();
bm.add(myBox);
bm.dispose();//is there benefit to doing this?
Run Code Online (Sandbox Code Playgroud) 在C#中,foreach是否会在任何实现IDisposable的对象上自动调用Dispose?
http://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx似乎表明它确实:
*否则,集合表达式是一个实现System.IEnumerable的类型,而foreach语句的扩展是:复制
IEnumerator enumerator =
((System.Collections.IEnumerable)(collection)).GetEnumerator();
try {
while (enumerator.MoveNext()) {
ElementType element = (ElementType)enumerator.Current;
statement;
}
}
finally {
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
}
Run Code Online (Sandbox Code Playgroud) 是否有任何指导或最佳实践,Dispose()
当他们被传递到另一个对象的方法或构造器时,谁应该调用一次性对象?
以下是我的意思的几个例子.
IDisposable对象被传递给一个方法(它应该在它完成后处理它吗?):
public void DoStuff(IDisposable disposableObj)
{
// Do something with disposableObj
CalculateSomething(disposableObj)
disposableObj.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
IDisposable对象被传递给一个方法并保留一个引用(它应该在处理时处置它MyClass
吗?):
public class MyClass : IDisposable
{
private IDisposable _disposableObj = null;
public void DoStuff(IDisposable disposableObj)
{
_disposableObj = disposableObj;
}
public void Dispose()
{
_disposableObj.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
我目前认为在第一个例子中,呼叫者的DoStuff()
,因为它可能创建的对象应该处理的对象.但是在第二个例子中,感觉MyClass
应该处理对象,因为它保留了对象的引用.这个问题是调用类可能不知道MyClass
已保留引用,因此可能决定在MyClass
完成使用之前处置该对象.这种情况是否有任何标准规则?如果存在,当一次性对象传递给构造函数时它们是否不同?
我有一个有一些非托管资源的类.我的类实现IDisposable
接口并释放方法中的非托管资源Dispose()
.我是否必须调用该Dispose()
方法或以某种方式自动调用?垃圾收集器会调用它吗?
idisposable ×10
c# ×8
.net ×4
dispose ×2
asp.net-mvc ×1
dbcontext ×1
duck-typing ×1
finalization ×1
finalizer ×1
foreach ×1
linq-to-sql ×1