gpt4 book ai didi

c# - 何时需要dispose()的规则是什么?

转载 作者:行者123 更新时间:2023-12-03 15:08:15 25 4
gpt4 key购买 nike

尽管我已经编码了一段时间,但实际上我只是勉强投入所谓的中级编码器中。因此,我了解dispose()的原理,该原理是释放为变量和/或资源保留的内存。我还发现有时使用EF时必须必须dispose()才能使其他操作正常工作。我不明白的是,什么时候需要使用dispose()才需要发布。
例如,我们不处理字符串,整数或 bool 值之类的变量。但是我们越过了一条“线”,需要处置我们使用的变量和/或资源。我不知道这条线在哪里。
知道何时使用dispose()时,是否有一个或几个基本原则适用?
我读了这些SO帖子(a specific situationmore about how rather than when),但是我不觉得我了解知道何时使用dispose()的基础知识。我看到一个评论问,当变量超出范围时是否释放内存,这引起了我的注意,因为直到我看到响应为否,才因为内存超出范围而不会释放它,所以我会认为当超出范围时,它确实会被释放。我不想成为第二个链接中的一个人,称为“笨拙的开发人员”,尽管我认为这有点苛刻。我们中有些人还在学习。
因此,这就是为什么我的问题是“由什么决定何时真正需要dispose()?”
我的问题不是如何之一,而是时是的问题。当然,有关如何使用它的注释,但是即使调用dispose()的方法是Using语句,我仍然需要知道何时。
编辑原始问题:我知道这是一个冗长的解释,因为被标记为重复的注释笔记请求,并且它不是一个问题,我只是不知道如何确保将重点放在我的确切问题上。通常,我们只是在问问题的过程中绊倒。正如我在这篇长篇文章的结尾提到的那样,假设我们到了这个问题,我将在专注于我的问题之后将所有内容全部编辑掉。根据我的阅读,我认为这是一个重要的问题。
建议的“answer”帖子是很棒的帖子,但并未真正回答我的问题。下面的CodeNotFound的注释也提供了一个很棒的链接,但它也不能真正回答我的问题。我提供了有关这些帖子的评论,以尝试帮助完善我的确切问题:
When should I dispose my objects in .NET?:第一个答案以注释开头

Disposable objects represent objects holding a valuable resource which the CLR is not intrinsically aware of.


不幸的是,我不明白“一次性对象... CLR本质上不了解”一词的含义。 我要的是。我如何知道某物是否属于我必须处置的类别?我们始终定义要在代码中使用的事物。我们什么时候越界,它变成我需要dispose()的对象?顺便说一句,我注意到该帖子的作者从未标记答案。我不知道这是否意味着他没有感觉到问题得到了回答,还是跟进他的工作进展不佳,但是我希望我已经做了一些我希望理解的事情。当您仔细查看答案时,它们并没有真正解决的问题,即对象需要开发人员的 Action 来处理它们,或者我不知道如何识别哪些对象。我只是不知道我创建的对象或东西需要我负责处理。而且我知道GC和其他规定也起作用了,但同样,这只是的方式。似乎清楚的是,大多数经验丰富且专业的开发人员都知道何时需要处理他们创建的内容。我不知道如何知道
和。
Proper use of the IDisposable interface:显然是一个很流行的答案(1681赞),但标记的答案始于

The point of Dispose is to free unmanaged resources".


好的,但是我的问题是,通过查看它是 非托管资源怎么知道的?而且我不明白以下说明如何适用于 和需要处理的

If you found it in the .NET framework it's managed. If you went poking around MSDN yourself, it's unmanaged... and you're now responsible for cleaning it up."


我不明白如何使用这种类型的解释来对我需要dispose()和不需要的东西进行分类。 .net框架中有各种各样的东西。如何将需要我的dispose()分离出来?我该怎么看才对我负责?
之后,答案就 进行了很长的发言,讨论了如何处置(),但我仍然对 停留在什么位置,需要处置。为了使这个话题更复杂,作者后来说:“现在我们将...

get rid of unmanaged resources (because we have to), and

get rid of managed resources (because we want to be helpful)


因此,现在我需要考虑处置一组使用内存的全新对象,而我也不知道它们是什么。答案的作者后来说

For anyone who likes the style of this answer (explaining the why, so the how becomes obvious)...


我了解作者在建议其他文章,但是作者建议理解“为什么”使“如何”变得显而易见并不是真正合法的,因为对一个人而言显而易见的对他人而言并不总是显而易见的。即便如此,作者还是更加关注 以及的原因和方式,而我的问题是关于时的 的含义,这意味着需要处置什么(),而不是在完成后处理 。当我完成时,我知道 ,但我完成时,我只是不知道 我负责的哪些事情。
对于大多数开发人员来说,应该处置什么可能是显而易见的或本能的,但对我而言这并不明显,我可以肯定,在我的经验阶段还有很多其他人,我希望就进行更集中的对话。 。当然为什么是有用的,但是在这种情况下,仅当为什么附加到时才是什么。例如:您必须处理DbContext ,因为CLR不会处理-,因为解释了为何使用,但在这种情况下,DbContext是,而必须处理的
我希望有一个通用原则,必须处理,而不是一长串的特定项目,这对于像我这样寻求简单指南的人来说不是特别有用。
再次,我意识到内存释放很重要,并且还有很多经验和专业知识用于学习为何如此,但是我仍然在努力了解,需要处置什么。一旦我了解了,我必须要处理什么,就可以开始学习,以了解如何做到这一点。
所以这仍然是一个不好的问题吗?我将在稍后编辑所有这些说明,以使这篇文章更加简洁,前提是我们能够更加专注于我要问的内容。
最终编辑:尽管我在上面说过,我会编辑掉原本认为是问题中不必要的文本的内容,但我认为最好保留它。我认为问题的提出方式有可能帮助我们理解答案。即使答案永远不会改变,但如果我们不将答案与我们构想问题的方式联系在一起,我们可能就无法真正理解答案。因此,如果该问题的提出方法与某人联系在一起,我建议您充分阅读标为答案的帖子以及评论。虽然最后的答案确实很简单,但是有很多历史和背景对于理解这个问题的答案很重要。为了清楚起见,在有关dispose()的整个讨论过程中,还对答案进行了来回编辑。享受...

最佳答案

I understand the principle of dispose(), which is to release memory reserved for variables and/or resources.



您是而不是了解处置的目的。用于释放与变量关联的内存的是而不是

What I don't understand is just exactly what requires a release, when to employ dispose().



确保已完成IDisposable的所有处理。

For example, we don't dispose variables like string, integer or booleans. But somewhere we cross 'a line' and the variables and/or resources we use need to be disposed. I don't understand where the line is.



该行已为您划定。当对象实现IDisposable时,应将其处置。

我注意到变量根本不是摆放的东西。 放置对象。对象不是变量,变量不是对象。变量是的存储位置。

Is there a single principle or a few broad principles to apply when knowing when to use dispose()?



一个单一的原则:当物体是一次性的时进行处置。

I don't feel like I understand the basics of knowing when to use dispose().



处置所有一次性物品。

One comment I saw asked if memory is released when a variable goes out of scope, and that got my attention because until I saw the response was no, it doesn't get released just because it goes out of scope, I would have thought that it does get released when it goes out of scope.



使用语言时要小心。您在混淆范围和生存期,并且使变量与变量的内容混淆。

首先:变量的范围是程序文本的区域,在该区域中可以通过名称来引用该变量。变量的生存期是程序执行期间的时间段,其中该变量被视为垃圾回收器的根。范围纯粹是一个编译时概念,生命周期纯粹是一个运行时概念。

作用域和生存期之间的联系是,局部变量的生存期通常在控件进入变量的作用域时开始,而在其离开时结束。但是,各种各样的事情都可能改变本地的生存期,包括在迭代器块或异步方法中被关闭。抖动优化器还可以缩短或延长本地设备的生命周期。

还请记住,变量是存储,并且它可能引用存储。当本地生存期结束时,可能会回收与本地
相关的存储。但是,无论何时何地,都无法保证与相关联的存储(本地引用的会被回收)。

So that's why my question is "What determines when a dispose() is really necessary?"



当对象实现IDisposable时,必须进行处理。 (有少量不需要处理的一次性对象。例如,任务。但是通常,如果是一次性的,则将其丢弃。)

My question is less one of how and more one of when.



完成处理后,才处置它。不是之前,也不是以后。

When should I dispose my objects in .NET?



当对象实现IDisposable时就对其进行处置,您就可以完成使用它们的工作。

How do I know if something falls into the category of what I must dispose?



当它实现IDisposable时。

I just don't know what objects or things I create require that I am responsible for disposing.



一次性的。

most experienced and professional developers know when something they've created needs to be disposed of. I don't understand how to know that.



他们检查对象是否是一次性的。如果是,他们将其处置。

The point of Dispose is to free unmanaged resources". OK, but my question is how do I know by looking at something that it is an unmanaged resource?



它实现IDisposable。

I don't understand how to use that type of explanation to categorize what I need to dispose() and what I don't. There's all kinds of stuff in the .net framework; how do I separate out things that require I dispose() of them? What do I look at to tell me I'm responsible for it?



检查它是否是IDisposable。

After that, the answer goes on to speak at great length about how to dispose(), but I'm still stuck back at what needs to be disposed.



任何实现IDisposable的东西都需要丢弃。

my question is about when, meaning what needs to be disposed(), as opposed to when I'm done with it. I know when I'm done with things, I just don't know which things I'm responsible for when I'm done with them.



实现IDisposable的东西。

I was hoping there is a general principle for what must be disposed rather than a long list of specific items which would not be particularly useful for people like me who are looking for simple guidelines.



简单的准则是您应该处理一次性物品。

Again, I get it that memory release is important, and also that a lot of experience and expertise goes into learning why and how, but I'm still left struggling to understand what needs to be disposed. Once I understand what I have to dispose(), then I can begin the struggle to learn how to do it.



通过调用Dispose()来处置实现IDisposable的事物。

So is this still a bad question?



这是一个非常重复的问题。

Your patience is a kindness.



感谢您在原意中幽默地回答了这个愚蠢的答案!

WRT scope != lifetime & variables != objects, very helpful.



这些都是很常见的混淆,并且在大多数情况下,它们几乎没有什么区别。但是我发现,经常难以理解一个概念的人并没有得到模糊和不精确的照顾。

In VS is it so simple as looking in Object Browser / Intellisense to see if the object includes Dispose()?



是的,绝大多数时间是这样。

有一些晦涩的角落案例。正如我已经提到的那样,TPL团队从中获得的智慧是,布置Task对象不仅是不必要的,而且会适得其反。

还有一些实现IDisposable的类型,但是使用“显式接口(interface)实现”技巧使“Dispose”方法只能通过转换为IDisposable来访问。在大多数情况下,对象本身都有Dispose的同义词,通常称为“Close”或某种类似的东西。我不太喜欢这种模式,但是有些人会使用它。

对于这些对象,using块仍将起作用。如果出于某种原因要不使用using显式处理此类对象,则(1)调用“Close”方法或任何被调用的方法,或者(2)强制转换为IDisposable并进行处理。

普遍的看法是:如果物体是一次性的,那么将其丢弃不会有任何伤害,并且当您完成处理时,这是一个好习惯。

原因是:一次性物品通常代表一种稀缺的共享资源。例如,一个文件的打开方式可能会拒绝打开该文件时其他进程访问该文件的权限。确保完成文件后立即关闭它是有礼貌的事情。如果一个进程想要使用文件,则另一个进程的可能性非常大。

或一次性物品可能代表类似图形对象的东西。如果一个进程中有超过一万个事件的图形对象,则操作系统将停止发出新的图形对象,因此,在使用完它们后,必须将它们放开。

WRT implementing IDisposable @Brian's comment suggests in "normal" coding I likely don't need to. So would I only do that if my class pulled in something unmanaged?



好问题。在两种情况下,您应该实现IDisposable。

(1)常见情况:您正在写一个对象,该对象长时间保持在另一个IDisposable对象上,并且“内部”对象的生存期与“外部”对象的生存期相同。

例如:您正在实现一个logger类,该类将打开一个日志文件并保持打开状态,直到关闭日志为止。现在您有了一门可处理的类,因此它本身也应该是可处理的。

我注意到,在这种情况下,不需要“外部”对象是可终结的。只是一次性的。如果出于某种原因从未在外部对象上调用该处理,则内部对象的终结器将负责终结处理。

(2)罕见的情况:您正在实现一个新类,该类向操作系统或其他外部实体询问必须积极清理的资源,并且该资源的生存期与持有该对象的对象的生存期相同。

在这种极为罕见的情况下,您应该首先问自己是否有任何避免方法。对于初学者到中级程序员来说,这是一个糟糕的情况。您确实需要了解CLR如何与非托管代码进行交互才能使这些东西变得可靠。

如果无法避免,您应该宁愿不要尝试自己实现处置和完成逻辑,如果非托管对象由Windows句柄表示,则特别是。由句柄表示的大多数OS服务应该已经有包装器,但是如果没有包装器,则要仔细研究IntPtr,SafeHandle和HandleRef之间的关系。 IntPtr, SafeHandle and HandleRef - Explained

如果您确实确实确实需要为不受管理的,非基于句柄的资源编写处置逻辑,并且该资源需要通过终结处理来支持处置,那么您将面临巨大的工程挑战。

标准的处理模式代码可能看起来很简单,但是编写正确的最终确定逻辑确实存在一些细微之处,而这些逻辑在遇到错误情况时会非常可靠。记住,终结器在不同的线程上运行,并且可以在线程异常终止场景中与构造函数同时在该线程上运行。编写线程安全逻辑以清理仍在另一个线程上构建的对象时,可能会非常困难,我建议您不要尝试。

有关编写终结器的挑战的更多信息,请参阅我关于该主题的系列文章:http://ericlippert.com/2015/05/18/when-everything-you-know-is-wrong-part-one/

您没有提出的问题,但我还是会回答:

Are there scenarios in which I should not be implementing IDisposable?



是的。许多人在希望具有以下语义的编码模式时都实现IDisposable:
  • 改变世界
  • 在新世界中做事
  • 还原更改

  • 因此,例如,“冒充管理员,执行一些管理任务,恢复为普通用户”。或“开始处理事件,在事件发生时进行处理,停止处理事件”。或“创建内存错误跟踪器,执行一些可能会导致错误的事情,停止跟踪错误”。等等。您将获得一般模式。

    这不太适合一次性模式,但这并不能阻止人们编写不代表任何非托管资源的类,但仍像他们一样实现IDisposable。

    这种意见使我成为少数派。这种机制的滥用对很多人来说都没有问题。但是,当我看到一个一次性用品时,我想“这个类(class)的作者希望我礼貌并在我准备好并且准备好后收拾自己”。但是,该类的实际约定通常是“您必须在程序中的某个特定点处进行处理,否则,程序逻辑的其余部分将一直是错误的,直到您这样做为止”。那不是我希望看到一次性物品时必须执行的契约(Contract)。我希望我必须尽一切努力在方便时清理资源。

    关于c# - 何时需要dispose()的规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35369238/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com