我在我的C#代码中使用了一个特定的命令,该代码运行良好.但是,据说在"非托管"代码中行为不端.
什么是托管代码或非托管代码?
虽然我已经编写了一段时间,但我真的只是进入了我所谓的中级编码器.所以我理解dispose()的原理,即释放为变量和/或资源保留的内存.我也发现有时使用EF我必须dispose()以便其他操作正常工作.我不明白的只是需要发布的内容,何时使用dispose().
例如,我们不处理变量,如字符串,整数或布尔值.但是在某个地方我们越过"一条线",我们使用的变量和/或资源需要被处理掉.我不明白这条线在哪里.
在知道何时使用dispose()时,是否有一个原则或几个广泛的原则适用?
我阅读了这些SO帖子(具体情况,更多关于如何而不是何时)但我不觉得我理解何时使用dispose()的基础知识.我看到一条评论询问是否在变量超出范围时释放内存,这引起了我的注意,因为直到我看到响应为否,它才会因为超出范围而被释放,我会想到当它超出范围时它会被释放.我不想成为第二个链接中的一个人称为"无能的开发者",虽然我认为这有点苛刻.我们中的一些人还在学习.
所以这就是为什么我的问题是"什么决定何时真正需要处置?"
我的问题是少一个多么多的一个时候.当然评论如何有用,但即使调用dispose()的方法是一个Using语句,我仍然需要知道什么时候.
编辑原始问题: 我知道这是一个很长的解释,标记为重复的评论笔记请求,这不是一个咆哮,我只是不知道如何确保我专注于我的精确问题.很多时候,我们只是匆匆走过我们问的方式.正如我在这篇长篇文章的最后提到的那样,在我们专注于我的问题后,我将编辑所有这些,假设我们到达那里.根据我所读到的内容,我认为这是一个重要的问题.
提议的"答案"帖子是一篇很棒的帖子,但并没有真正回答我的问题.CodeNotFound下面的评论也提供了一个很好的链接,但它也没有真正回答我的问题.我提供了有关这些帖子的评论,以尝试帮助改进我的确切问题:
我什么时候应该在.NET中处理我的对象?:第一个答案以评论开头
一次性对象表示持有CLR本质上不知道的有价值资源的对象.
不幸的是,我不明白" 一次性对象...... CLR本质上没有意识到 " 这一术语包括在内. 这就是我要问的问题.我怎么知道某件事是否属于我必须处理的范畴?我们一直在代码中定义要使用的东西.我们何时越过这条线并成为我需要处置的对象()?顺便说一句,我注意到那篇文章的作者从未标出答案.我不知道这是否意味着他不觉得这个问题得到了回答,或者他的跟进是否很差,但我希望我能够提炼一点我希望了解的内容.当你仔细观察答案时,他们并没有真正解决哪些对象需要开发人员处理它们的问题,或者我如何知道如何识别哪些对象.我只是不知道我创建的对象或事物需要我负责处理.我认为GC和其他条款发挥作用,但同样,这就是方法.显而易见的是,大多数经验丰富的专业开发人员都知道他们创建的东西何时需要被处理掉.我不明白怎么知道那.
正确使用IDisposable界面:显然是一个流行的答案(1681 upvotes),但明确的答案开始于
Dispose的目的是释放非托管资源".
好的,但我的问题是如何通过查看它是非托管资源的东西来了解?我不理解以下说明如何应用到什么需要处置.
如果你在.NET框架中找到它,那么它就是托管的.如果你自己去探索MSDN,它是无人管理的 ...你现在负责清理它."
我不明白如何使用这种类型的解释来分类我需要处理的东西()和我不需要的东西..net框架中有各种各样的东西; 如何分离出需要我处理它们的东西?我该怎么看我告诉我我对此负责?
在那之后,这个答案就在约大篇幅讲了如何处置(),但我仍然停留在背什么需要处置.为了让这个话题进一步复杂化,该作者后来说:"现在我们将...
摆脱非托管资源(因为我们必须),和
摆脱托管资源(因为我们想要帮助)
所以现在我需要考虑处理一组使用内存的全新对象,我不知道它们是什么.该答案的作者后来说
对于任何喜欢这种答案风格的人(解释原因,如何变得明显)......
我理解作者是在暗示其他文章,但作者的建议是理解"为什么"使得"如何"显而易见并不合法,因为对一个人来说显而易见的事情对另一个人来说并不总是显而易见的.甚至在那时,作者更多地关注为什么以及如何,并且我的问题是什么时候,意味着什么需要被处理(),而不是当我完成它时.我知道当我做完事情时,我只是不知道 …
我一直在研究从数据库中提取大量记录的数据导出程序.其中一个步骤涉及将RTF文本字符串转换为纯文本,这最终导致用户对象在运行时发生内存泄漏.任务管理器将显示的一个列是"USER对象" - 当达到~10,000时,程序将耗尽分配空间,程序将出现"错误创建窗口句柄"
发生这种情况是因为我没有在方法结束时处理我的对象.
我的问题是,为什么C#/.net不为我处理它?
这是一个快速重现漏洞的代码示例.将代码放入Winforms应用程序并按下按钮以使其循环通过内存浪费.
private void wasteMemory()
{
System.Windows.Forms.RichTextBox rtfBox = new System.Windows.Forms.RichTextBox();
//RTF text that reads "Hello World"
rtfBox.Rtf = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}} {\\colortbl ;\\red0\\green0\\blue0;} \\viewkind4\\uc1\\pard\\cf1\\fs29 Hello World} ";
//If line below is commented out, User Objects grow out of control.
//rtfBox.Dispose();
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 1; i < 100000; i++)
{
wasteMemory();
}
}
Run Code Online (Sandbox Code Playgroud)
我的理解是,当方法完成时,处理在其侧面创建的任何对象的方法范围.我期望rtfBox被处理掉,但事实并非如此.