何时需要dispose()的规则是什么? [英] What are the rules for when dispose() is required?

查看:160
本文介绍了何时需要dispose()的规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管我已经编码了一段时间,但实际上我只是勉强了解所谓的中级编码器。因此,我了解dispose()的原理,该原理是释放为变量和/或资源保留的内存。我还发现有时使用EF时必须必须dispose()才能使其他操作正常工作。我不明白的是,到底什么才需要发布,何时使用dispose()。

Although I have been coding for some time, I'm really just barely into what I would call an intermediate level coder. So I understand the principle of dispose(), which is to release memory reserved for variables and/or resources. I have also found sometimes using EF I have to dispose() in order for other operations to work properly. What I don't understand is just exactly what requires a release, when to employ dispose().

例如,我们不处理字符串,整数或布尔值。但是,在我们跨越界线的地方,我们需要处理使用的变量和/或资源。我不知道这行在哪里。

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.

知道何时使用dispose()时,是否有一个或几个基本原则可以应用?

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

我阅读了这些SO帖子(特定情况更多有关如何而不是何时的信息),但我不觉得就像我了解知道何时使用dispose()的基本知识。我看到一个评论问,当变量超出范围时是否释放了内存,这引起了我的注意,因为直到我看到响应为否,才因为内存超出范围而不会释放它,我会认为当超出范围时,它确实会被释放。我不想成为第二个链接中的无知开发人员,尽管我认为这有点苛刻。我们中有些人还在学习。

I read these SO posts (a specific situation, more about how rather than when ) but 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. I don't want to be what one person in the 2nd link called a 'clueless developer', although I thought that was a little harsh. Some of us are still learning.

所以这就是为什么我的问题是什么决定何时真正需要dispose()?

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

我的问题不是如何的问题之一,而是何时的问题之一。当然,有关如何使用它的评论也可以,但是即使调用dispose()的方法是Using语句,我仍然需要知道何时。

My question is less one of how and more one of when. Of course comments on how would be useful, but even if the method for invoking dispose() is a Using statement, I still need to know when.

编辑原始问题:我知道这是一个很长的解释,因为标记为重复的注释便条要求,而且这不是语,我只是不知道如何确保获得专注于我的确切问题。通常,我们只是在问问题的过程中绊倒。正如我在这篇长篇文章的结尾提到的那样,假设我们到了这个问题,我将在专注于我的问题之后将所有内容全部编辑掉。根据我的阅读,我认为这是一个重要的问题。

Edit to original question: I know this is a long explanation as the marked as duplicate comment note requests, and it's not a rant, I just don't know how to make sure I get the focus on my precise question. Often times we just trip up over the way we ask something. As I mention at the end of this long text I'll edit all this out after we've gotten focused on my issue, assuming we get there. Based on what I've read, I think it's an important question.

建议的 answer帖子是 great 帖子,但没有并没有真正回答我的问题。下面的CodeNotFound的注释也提供了一个出色链接,但它也无法真正回答我的问题。我提供了有关这些帖子的评论,以尝试帮助完善我的确切问题:

The proposed "answer" post is a great post, but doesn't really answer my question. CodeNotFound's comment below also gives a great link but it doesn't really answer my question either. I've provided comments regarding these posts to try and help refine my precise question:

何时应该在.NET中放置对象?:第一个答案以注释开头

When should I dispose my objects in .NET?: The first answer starts with a comment that


一次性对象表示持有CLR本身并不了解的宝贵资源的对象。

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

很遗憾,我不理解 一次性对象... CLR本质上不了解一词的含义。 那是我要的。我如何知道某物是否属于我必须处置的类别?我们始终定义要在代码中使用的事物。我们什么时候越界,它变成我需要dispose()的对象?顺便说一句,我注意到该帖子的作者从未标记答案。我不知道这是否意味着他不觉得问题得到了回答,或者跟进他的工作是否进展不佳,但希望我已经做了一些我希望理解的事情。当您仔细查看答案时,它们并没有真正解决哪些对象需要开发人员采取行动来处置它们的问题,或者我可能会去了解如何识别 对象。我只是不知道我创建的对象或东西需要我负责处理。我知道GC和其他条款已开始发挥作用,但同样,这只是方法。似乎清楚的是,大多数经验丰富且专业的开发人员都知道何时需要处理他们创建的内容。我不知道如何知道

Unfortunately I don't understand what the term "Disposable objects ... the CLR is not intrinsically aware of" includes. That's what I'm asking. How do I know if something falls into the category of what I must dispose? We define things to use in code all the time. When do we cross the line and it becomes an object I need to dispose()? BTW, I noticed the author of that post never marked an answer. I don't know if that means he didn't feel the question was answered or if it was just poor follow up on his part, but hopefully I've refined a little what I hoping to understand. When you look closely at the answers, they're not really addressing the issue of which objects require a developer's action to dispose() of them, or how I might go about knowing how to identify which objects. I just don't know what objects or things I create require that I am responsible for disposing. And I get it that GC and other provisions come into play, but again, that's just the how. What seems clear is that most experienced and professional developers know when something they've created needs to be disposed of. I don't understand how to know that.

正确使用IDisposable接口:显然是一个很流行的答案(1681赞),但是标记的答案始于

Proper use of the IDisposable interface: Clearly a popular answer (1681 upvotes), but the marked answer begins with


处置的目的是释放不受管理的资源。

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? And I don't understand how the note that follows applies to what needs to be disposed.


如果您在.NET框架中找到它,则由管理。如果您自己戳MSDN, ,它是不受管理的 ...,您现在要负责清理它。

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()分离出来?我该怎么看才对我负责?

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?

在那之后,答案继续很长地谈到如何进行dispose(),但我仍然对什么需要处理。为了使这个话题进一步复杂化,该作者后来说:现在我们将...

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. To further complicate the topic for me, that author later says "So now we will...


摆脱不受管理的资源(因为我们必须),

摆脱托管资源(因为我们想提供帮助)

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

所以现在我需要考虑处置一组使用内存的全新对象,我也不知道它们是什么。答案的后面说

So now I need to consider disposing a whole new set of objects that use memory, and I don't know what those are either. The author of the answer later says


对于任何喜欢此答案样式的人(解释原因,显而易见的原因)...

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

我了解作者在建议其他文章,但是作者建议理解为什么使如何变得明显真的合法,因为对一个人而言显而易见的事物对另一人而言并不总是显而易见的。即使如此,作者还是将重点更多地放在了为什么和如何上,而我的问题是关于何时,这意味着什么需要处理(),而不是何时。我知道何时完成,我只是不知道何时完成的是我负责的事情。

I understand the author was suggesting other articles, but the author's suggestion that understanding the "why" makes the "how" obvious isn't really legitimate because what's obvious to one person isn't always obvious to another. And even at that, the author focused more on the why and how, and 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.

对于大多数开发人员来说,需要处置的东西可能是显而易见的或本能的,但对我和我来说并不明显。确保在我的经验阶段还有很多其他人,我希望就内容进行更集中的对话。当然为什么是有用的,但是在这种情况下,只有将为什么附加到内容上。例如:您必须处置DbContext,因为因为 CLR不会处置它-因为解释了为什么,但是在这种情况下, DbContext是必须处理的什么

It may be obvious or instinctive to most developers what needs to be disposed(), but it's not obvious to me and I'm sure many others at my stage of experience and I was hoping to get a more focused dialogue on what. Certainly why is useful, but in this case only if the why is attached to a what. For example: You have to dispose a DbContext because the CLR won't dispose it - the because explains why, but in this case, it's the DbContext that is the what that must be disposed.

我希望对什么有一个通用原则必须处理掉,而不是列出一长串的特定项目,对于像我这样正在寻找简单指南的人来说,这并不是特别有用。

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.

所以这仍然是一个不好的问题吗?假设我们能够更加专注于我要问的内容,我将在稍后删除所有这些解释,以使帖子更加简洁。

So is this still a bad question? I'll edit out all of this explanation later to leave the post more succinct assuming we're able to achieve more focus on what I'm asking.

最终编辑::尽管我在上面说过,我会删除本来认为是问题中不必要的文本,但最好还是保留下来。我认为问题的提出方式有可能帮助我们理解答案。即使答案永远不会改变,但如果我们不将答案与我们构想问题的方式联系在一起,我们可能就无法真正理解答案。因此,如果该问题的提出方法与某人联系在一起,我建议您充分阅读标为答案的帖子以及评论。尽管答案很简单,但是有很多历史和背景对于理解该问题的答案很重要。为了清楚起见,在有关dispose()的整个讨论过程中,还对答案进行了来回编辑。享受...

Final Although I said above I would edit out what I originally thought to be unnecessary text in the question, I think it better to leave it in. I think the way questions are asked has the potential to help us understand the answer. Even though the answer never changes, if we don't connect the answer to the way we framed the question in our minds, we may not really understand the answer. So if the way this question was framed connects with someone, I encourage you to fully read the post marked as the answer, along with the comments. While the answer in the end was really simple, there's a great deal of history and also context that is important to understand the answer to this question. For clarity's sake, the answer was also edited back and forth over the life of this discussion regarding dispose(). Enjoy...

推荐答案


我了解dispose()的原理,即释放内存为变量和/或资源保留。

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

理解处置的目的。 不是用于释放与变量相关联的内存。

You do not understand the purpose of dispose. It is not for releasing memory associated with variables.


我不明白的正是所需要的发布时,何时使用dispose()。

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

当您确定时,请处置任何实现IDisposable的东西

Dispose anything that implements IDisposable when you are sure that you are done with it.


例如,我们不处理字符串,整数或布尔值之类的变量。但是,在我们跨越界线的地方,我们需要处理使用的变量和/或资源。我不知道该行的位置。

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时,应该将其处置。

The line is demarcated for you. When an object implements IDisposable, it should be disposed.

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

I note that variables are not things that are disposed at all. Objects are disposed. Objects are not variables and variables are not objects. Variables are storage locations for values.


知道时是否有一个或几个基本原则适用何时使用dispose()?

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

一个原则:当对象是一次性的时处置。

A single principle: dispose when the object is disposable.


我不觉得我了解知道何时使用dispose()的基础。

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

全部丢弃一次性物品。

Dispose all objects that are disposable.


我看到一条评论,询问当变量超出范围时是否释放内存,这引起了我的注意,因为直到我看到响应是的,它不会因为超出范围而被释放,我会以为它在超出范围时会被释放。

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.

请谨慎使用语言。您正在混淆范围和生命周期,并且将变量与变量的内容相混淆。

Be careful in your use of language. You are confusing scope and lifetime, and you are confusing variables with the contents of the variables.

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

First: the scope of a variable is the region of program text in which that variable may be referred to by name. The lifetime of a variable is the period of time during the execution of the program in which the variable is considered to be a root of the garbage collector. Scope is purely a compile-time concept, lifetime is purely a run-time concept.

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

The connection between scope and lifetime is that a local variable's lifetime is often starting when control enters the scope of the variable, and ending when it leaves. However, various things can change the lifetime of a local, including being closed over, in an iterator block, or in an async method. The jitter optimizer may also shorten or extend the life of a local.

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

Remember also that a variable is storage, and that it may refer to storage. When the lifetime of a local ends, the storage associated with the local might be reclaimed. But there is no guarantee whatsoever that the storage associated with the thing the local refers to will be reclaimed, at that time or ever.


所以这就是为什么我的问题是什么决定何时真正需要dispose()?

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

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

Dispose is necessary when the object implements IDisposable. (There are a small number of objects that are disposable that need not be disposed. Tasks, for instance. But as a general rule, if it is disposable, dispose it.)

我的问题不是一种方法,而一种是何时。

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

仅在完成处理后处置它。

Only dispose a thing when you are done with it. Not before, and not later.


何时应该在.NET中放置对象?

When should I dispose my objects in .NET?

当对象实现IDisposable时就将其丢弃,您就可以使用它们了。

Dispose objects when they implement IDisposable, and you are done using them.

我怎么知道某物是否属于我必须处置的东西?

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

当实现IDisposable时。

When it is implementing 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.

他们检查对象是否为一次性物品。

They check to see if the object is disposable. If it is , they dispose it.


Dispose的目的是释放不受管理的资源。好吧,但是我的问题是我该如何处理。

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。

It implements IDisposable.


我不明白如何使用这种解释来对我需要dispose()和不需要的东西进行分类。如何将需要我的dispose()分离出来?我要告诉我我要对此负责吗?

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的。

Check to see if it is 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的东西都需要处理。

Anything that implements IDisposable needs to be disposed.


我的问题是关于w母鸡,意思是需要处置的东西,而不是当我用完它时。我知道当我完成工作时,我只是不知道当我完成工作时我要负责哪些事情。

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的东西。

The things that implement 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。

Dispose things that implement IDisposable by calling Dispose().


所以这还是一个不好的问题吗?

So is this still a bad question?

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

It is a very repetitive question.


<你的耐心是一种善良。

Your patience is a kindness.

感谢您在预期的幽默中回答了这个有点愚蠢的答案!

Thanks for taking this somewhat silly answer in the humour in which it was intended!


WRT范围!=生命周期&变量!=对象,非常有帮助。

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

这些通常很混乱,在大多数情况下,它们没有什么区别。但是我发现,经常难以理解一个概念的人根本就不会因为模糊和不精确而得到满足。

These are very commonly confused, and most of the time, it makes little difference. But I find that often people who are struggling to understand a concept are not at all well served by vagueness and imprecision.


在VS中在对象浏览器/ Intellisense中查看对象是否包含Dispose()这么简单?

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

绝大多数时候,是的。

The vast majority of the time, yes.

有一些不起眼的案例。正如我已经提到的,TPL团队所接受的智慧是,布置Task对象不仅是不必要的,而且会适得其反。

There are some obscure corner cases. As I already mentioned, the received wisdom from the TPL team is that disposing Task objects is not only unnecessary, but can be counterproductive.

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

There are also some types that implement IDisposable, but use the "explicit interface implementation" trick to make the "Dispose" method only accessible by casting to IDisposable. In the majority of these cases there is a synonym for Dispose on the object itself, typically called "Close" or some such thing. I don't much like this pattern, but some people use it.

对于那些对象,使用 using 块仍然可以工作。如果出于某种原因您想显式地处置此类对象而不使用 ,则可以(1)调用 Close方法,也可以调用它,或者(2)强制转换

For those objects, the using block will still work. If for some reason you want to explicitly dispose such objects without using using then either (1) call the "Close" method, or whatever it is called, or (2) cast to IDisposable and dispose it.

通常的智慧是:如果对象是可丢弃的,则对其进行处置不会有任何伤害,并且当将其丢弃时,这是一个好习惯

The general wisdom is: if the object is disposable then it does not hurt to dispose it, and it is a good practice to do so when you're done with it.

原因是:一次性对象通常代表稀缺的共享资源。例如,一个文件的打开方式可能会拒绝打开该文件时其他进程访问该文件的权限。有礼貌的做法是确保在处理完文件后立即将其关闭。如果一个进程想要使用文件,那么另一个进程的赔率将很快。

The reason being: disposable objects often represent a scarce shared resource. A file, for example, might be opened in a mode that denies the rights of other processes to access that file while you have it opened. It's the polite thing to do to ensure that the file is closed as soon as you're done with it. If one process wanted to use a file, odds are pretty good another one will soon.

或者一次性文件可能代表图形对象。如果一个进程中有上万个活动的图形对象,则操作系统将停止发出新的图形对象,因此,在使用完它们后,必须将它们放开。

Or a disposable might represent something like a graphics object. The operating system will stop giving out new graphics objects if there are more than ten thousand active in a process, so you've got to let them go when you're done with them.


实现IDisposable的WRT @Brian的评论暗示我可能不需要正常编码。因此,如果我的班级加入了一些不受管的东西,我只会这样做吗?

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。

Good question. There are two scenarios in which you should implement IDisposable.

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

(1) The common scenario: you are writing an object that holds onto another IDisposable object for a long time, and the lifetime of the "inner" object is the same as the lifetime of the "outer" object.

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

For example: you are implementing a logger class that opens a log file and keeps it open until the log is closed. Now you have a class that is holding onto a disposable, and so it itself should also be disposable.

我注意到在这种情况下,外部无需使用可以最终确定的对象。只是一次性的。如果出于某种原因从未在外部对象上调用dispose,则内部对象的终结器将负责终结处理。

I note that there is no need in this case for the "outer" object to be finalizable. Just disposable. If for some reason the dispose is never called on the outer object, the finalizer of the inner object will take care of finalization.

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

(2) the rare scenario: you are implementing a new class which asks the operating system or other external entity for a resource that must be aggressively cleaned up, and the lifetime of that resource is the same as the lifetime of the object holding onto it.

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

In this exceedingly rare case you should first, ask yourself if there is any way to avoid it. This is a bad situation to be in for a beginner-to-intermediate programmer. You really need to understand how the CLR interacts with unmanaged code in order to get this stuff solid.

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

If you cannot avoid it, you should prefer to not attempt to implement the disposal and finalization logic yourself, particularly if the unmanaged object is represented by a Windows handle. There should already be wrappers around most of the OS services represented by handles, but if there is not one, what you want to do is carefully study the relationship between IntPtr, SafeHandle and HandleRef. IntPtr, SafeHandle and HandleRef - Explained

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

If you really truly do need to write the disposal logic for an unmanaged, non-handle-based resource, and the resource requires backstopping the disposal with finalization, then you have a significant engineering challenge.

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

The standard dispose pattern code may look simple but there are real subtleties to writing correct finalization logic that is robust in the face of error conditions. Remember, a finalizer runs on a different thread and can run on that thread concurrent with the constructor in thread abort scenarios. Writing threadsafe logic which cleans up an object while it is still being constructed on another thread can be extraordinarily difficult and I recommend against trying.

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

For more on the challenges of writing finalizers, see my series of articles on the subject: http://ericlippert.com/2015/05/18/when-everything-you-know-is-wrong-part-one/

一个您没有问过的问题,但我还是会回答:

A question you did not ask but I will answer anyways:


在某些情况下,我应该不是正在实现IDisposable吗?

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

是。许多人在希望具有以下语义的编码模式时都实现IDisposable:

Yes. Many people implement IDisposable any time they wish to have a coding pattern that has the semantics of:


  • 改变世界
  • >
  • 在新世界做事

  • 还原更改

  • Make a change in the world
  • Do stuff in the new world
  • Revert the change

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

So, for example, "impersonate an administrator, do some admin tasks, revert to normal user". Or "start handling an event, do stuff when the event happens, stop handling the event". Or "create an in-memory error tracker, do some stuff that might make errors, stop tracking errors". And so on. You get the general pattern.

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

This is a poor fit for the disposable pattern, but that doesn't stop people from writing up classes that represent no unmanaged resource whatsoever, but still implement IDisposable as though they did.

这种观点使我处于少数派;这种机制的滥用对很多人来说都没有问题。但是,当我看到一个一次性物品时,我想这个班级的作者希望我保持礼貌,并在我准备好并且准备好后,自己整理一下。但是,该类的实际契约通常是您必须将其放置在程序中的特定点,如果不这样做,则其余程序逻辑将是错误的。直到你这样做。那不是我希望看到一次性物品时必须执行的合同。我希望我必须认真努力清理方便的资源。

This opinion puts me in a minority; lots of people have no problem whatsoever with this abuse of the mechanism. But when I see a disposable I think "the author of this class wishes me to be polite and clean up after myself when I am good and ready." But the actual contract of the class is often "you must dispose this at a particular point in the program and if you do not then the rest of the program logic will be wrong until you do". That is not the contract I expect to have to implement when I see a disposable. I expect that I have to make a good-faith effort to clean up a resource at my convenience.

这篇关于何时需要dispose()的规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆