So I have a game object that contains a class A (extends monobehavior) that contains(creates) a class B (no monobehavior). This class B spawns a thread that contains a while (true) loop which does some work.
My question is...
When this GameObject is disposed/destroyed , I assume the class B contained inside of it is destructed as well. When this class B is destructed, is this infinite loop thread terminated as well?
Threads that have been started, principally run until the main thread ends. This is a OS level fallback, to avoid Zombie Threads without a owning application. However, it is not a fallback you should rely on. A Thread once started should be seen as a unmanaged resource, so cleanup code should be in place. The Dispose pattern in particular.
There is this wonderfull article on how to do it, but I feel it needs a explanation. You generally have to differentiate two cases with the Dispose pattern:
You are working with a Unamanged resource directly. In that case you write the Finalizer first. Then provide Dispose as a convenient way to clean stuff up on a programmers decision.
You are handling or may be handling something that implements IDisposeable. In that case, all you implement is the Dispose part and for the sole purpose of cascading teh call down to the Disposeable stuff you wrap around.
95% of all classes only implement IDisposeable because of case 2. We do not know if there actually is anything Disposeable, or if that was just part of a abstract base class.
Thread does not implement Dispose (I have no idea why), so you got a rare case 1. Dispose and Finalizer are often also compressed into one method - usually the Dispose one - as their code is very similar. The only real difference between Finalize and Dispose is cascading behavior:
When Finalizing, you never cascade. Finalisation is between this instance and the GC.
When Disposing, you always cascade (when possible). Most of the cases it is only there to allow cascading.
My final advice is, that since you are working with Multithreading you have to take care not to swallow Exceptions. Normally you got to write really bad code for to swallow Exceptions, but with Multitasking you have to go out of your way to not swallow any. I can not find any indication that Thread has a build in mechanic to persist exceptions (I know for a fact that Task does). All I can give you is the two articles on exception handling I link often:
https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/
https://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET
Related
EDIT
See edit note at the bottom of the question for additional detail.
Original question
I have a CacheWrapper class which creates and holds onto an instance of the .NET MemoryCache class internally.
MemoryCache hooks itself into AppDomain events, so it will never be garbage-collected unless it is explicitly disposed. You can verify this with the following code:
Func<bool, WeakReference> create = disposed => {
var cache = new MemoryCache("my cache");
if (disposed) { cache.Dispose(); }
return new WeakReference(cache);
};
// with false, we loop forever. With true, we exit
var weakCache = create(false);
while (weakCache.IsAlive)
{
"Still waiting...".Dump();
Thread.Sleep(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
}
"Cleaned up!".Dump();
Because of the behavior, I believe that my MemoryCache instance should be treated as an unmanaged resource. In other words, I should ensure that it is disposed in the finalizer of CacheWrapper (CacheWrapper is itself Disposable follows the standard Dispose(bool) pattern).
However, I am finding that this causes issues when my code runs as part of an ASP.NET app. When the application domain is unloaded, the finalizer runs on my CacheWrapper class. This in turn attempts to dispose the MemoryCache instance. This is where I run into issues. It seems that Dispose attempts to load some configuration information from IIS, which fails (presumably because I'm in the midst of unloading the app domain, but I'm not sure. Here's the stack dump I have:
MANAGED_STACK:
SP IP Function
000000298835E6D0 0000000000000001 System_Web!System.Web.Hosting.UnsafeIISMethods.MgdGetSiteNameFromId(IntPtr, UInt32, IntPtr ByRef, Int32 ByRef)+0x2
000000298835E7B0 000007F7C56C7F2F System_Web!System.Web.Configuration.ProcessHostConfigUtils.GetSiteNameFromId(UInt32)+0x7f
000000298835E810 000007F7C56DCB68 System_Web!System.Web.Configuration.ProcessHostMapPath.MapPathCaching(System.String, System.Web.VirtualPath)+0x2a8
000000298835E8C0 000007F7C5B9FD52 System_Web!System.Web.Hosting.HostingEnvironment.MapPathActual(System.Web.VirtualPath, Boolean)+0x142
000000298835E940 000007F7C5B9FABB System_Web!System.Web.CachedPathData.GetPhysicalPath(System.Web.VirtualPath)+0x2b
000000298835E9A0 000007F7C5B99E9E System_Web!System.Web.CachedPathData.GetConfigPathData(System.String)+0x2ce
000000298835EB00 000007F7C5B99E19 System_Web!System.Web.CachedPathData.GetConfigPathData(System.String)+0x249
000000298835EC60 000007F7C5BB008D System_Web!System.Web.Configuration.HttpConfigurationSystem.GetApplicationSection(System.String)+0x1d
000000298835EC90 000007F7C5BAFDD6 System_Configuration!System.Configuration.ConfigurationManager.GetSection(System.String)+0x56
000000298835ECC0 000007F7C63A11AE System_Runtime_Caching!Unknown+0x3e
000000298835ED20 000007F7C63A1115 System_Runtime_Caching!Unknown+0x75
000000298835ED60 000007F7C639C3C5 System_Runtime_Caching!Unknown+0xe5
000000298835EDD0 000007F7C7628D86 System_Runtime_Caching!Unknown+0x86
// my code here
Is there any known solution to this? Am I correct in thinking that I do need to dispose the MemoryCache in the finalizer?
EDIT
This article validates Dan Bryant's answer and discusses many of the interesting details. In particular, he covers the case of StreamWriter, which faces a similar scenario to mine because it wants to flush it's buffers upon disposal. Here's what the article says:
Generally speaking, finalizers may not access managed objects.
However, support for shutdown logic is necessary for
reasonably-complex software. The Windows.Forms namespace handles this
with Application.Exit, which initiates an orderly shutdown. When
designing library components, it is helpful to have a way of
supporting shutdown logic integrated with the existing
logically-similar IDisposable (this avoids having to define an
IShutdownable interface without any built-in language support). This
is usually done by supporting orderly shutdown when
IDisposable.Dispose is invoked, and an abortive shutdown when it is
not. It would be even better if the finalizer could be used to do an
orderly shutdown whenever possible.
Microsoft came up against this problem, too. The StreamWriter class
owns a Stream object; StreamWriter.Close will flush its buffers and
then call Stream.Close. However, if a StreamWriter was not closed, its
finalizer cannot flush its buffers. Microsoft "solved" this problem by
not giving StreamWriter a finalizer, hoping that programmers will
notice the missing data and deduce their error. This is a perfect
example of the need for shutdown logic.
All that said, I think that it should be possible to implement "managed finalization" using WeakReference. Basically, have your class register a WeakReference to itself and a finalize action with some queue when the object is created. The queue is then monitored by a background thread or timer which calls the appropriate action when it's paired WeakReference gets collected. Of course, you'd have to be careful that your finalize action doesn't inadvertantly hold onto the class itself, thus preventing collection altogether!
You can't Dispose managed objects in the finalizer, as they might have already been finalized (or, as you've seen here, portions of the environment may no longer be in the state you're expecting.) This means that if you contain a class which must be Disposed explicitly, your class must also be Disposed explicitly. There's no way to 'cheat' and make the Disposal automatic. Unfortunately, garbage collection is, in cases like this, a leaky abstraction.
I would suggest that objects with finalizers should generally not be exposed to the outside world, and should only hold strong references to things which are actually needed for finalization and are not exposed to anything in the outside world that is not expecting them to be used for that purpose. Public-facing types should not have finalizers themselves, but should instead encapsulate cleanup logic within privately-held instances of finalizable classes whose purpose is to encapsulate such logic.
The only time it really makes sense for a finalizer to attempt to clean up a resource which is owned by another object is when the other object is designed to interface with the finalizer. I can't think of any places where Framework classes have engineered in the proper hooks, but will offer an example how Microsoft could have engineered them to do so.
A File object could offer an event with thread-safe subscribe and unsubscribe methods which would fire (notifying the last subscriber first) when the File object receives either a Dispose call or a finalize request. The event would fire between the time Finalize is called and the time the encapsulated file is actually closed, and could be used by a an external buffering class as a signal that it needs to give the File any information which it has received but not yet passed along.
Note that to make such a thing work properly and safely, it would be necessary that the part of the File object which has the finalizer not be exposed to the public, and that it use a long weak reference to ensure that if it runs while the public-facing object is still alive, it will reregister itself for finalization. Note that if the only reference to a WeakReference object is stored in a finalizable object, its Target property may be invalidated if the finalizable object becomes eligible for finalization even if the actual target of the reference is still alive. Defective design, IMHO, and one which must be worked around somewhat carefully.
It's possible to design objects with finalizers that can cooperate (the easiest way to do it, generally, is to only have one object in the group sport a finalizer), but if things aren't designed to cooperate with finalizers, the best that one can do is generally have a finalizer sound an alarm indicating "This object wasn't supposed to be Disposed but wasn't; because it wasn't, resources are going to leak, and there's nothing to be done about it except fix the code to dispose the object properly in future".
I need to ensure thread safety when disposing an IDisposable resource. The resource is cached multiple times in memory. When entries are evicted from the cache we have a callback that calls Dispose().
Therefore if the resource is cached three times, we'll call Dispose() three times.
Is it the responsibility of the IDisposable resource to ensure thread safety or the caller?
It is the responsibility of the class implementing the IDisposable interface to ensure that the method can be called multiple times without throwing exception.
To help ensure that resources are always cleaned up appropriately, a Dispose method should be callable multiple times without throwing an exception.
http://msdn.microsoft.com/en-us/library/fs2xkftw(v=vs.110).aspx
After an object is disposed, calls that fail because the object is disposed can and likely should throw an ObjectDisposedException (to aid in future debugging). If it is important that external objects know whether or not an object is disposed before making calls (because the object is shared), then it is customary to add a public boolean property (IsDisposed/Disposed) that indicates the state of the object.
EDIT: To more clearly cast this answer to the phrasing of the question, the class implementing IDisposable should implementing thread-safety if it is expected the class will be used in a cross-threaded environment. The link I posted shows an example of this at the bottom of the page.
Either
The system which is evicting the values and calling Dispose must use synchronization to ensure the calls don't overlap
The object itself must implement Dispose in such a way that it can be safely called from multiple threads
Both of these are completely valid solutions to the problem. Which one is better will depend a lot on your system.
All other things being equal I would opt for #2. I prefer to have my objects be self sufficient and require as little help as possible to successfully execute in the environment they are designed for. Making it thread safe reduces the knowledge the rest of the system needs to use it correctly
The answer depends on whether the objects you want to dispose adhere to the guidelines or not.
If they do some things get simpler, from IDisposable.Dispose:
If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed.
So if calling Dispose multiple times has no effect other than the first time it's called you only have to ensure that you don't call them at the same time. And that should absolutely be the responsibility of the caller.
Stephen Cleary wrote an article on CodeProject about how to implement IDisposable and the possible problems which I find extremely helpful.
Is it the responsibility of the IDisposable resource to ensure thread safety or the caller?
It is up to the caller to guarantee thread safety through lock primitive or Monitor class IDisposable has nothing to do with thread safety. It's just a signal that the object's instance is ready to be garbage collected.
(1) I've read a lot of questions about IDisposable where the answers recommend not using Finalize unless you really need to because of the process time involved.
What I haven't seen is how much this cost is and how often it's paid. Every millisecond? second? hour, day etc.
(2) Also, it seems to me that Finalize is handy when its not always known if an object can be disposed. For instance, the framework font class. A control can't dispose of it because it doesn't know if the font is shared. The font is usually created at design time so the user won't know to dispose it, therefore finalize kicks in to finally get rid of it when there are no references left. Is that a correct impression?
The main problem with finalize is that it blocks an object from being garbage collected. Instead, the finalizer is called, and the object collected "on the next run". Well, technically IIRC the finalizer runs a list of objects in a separate thread. Anyhow, this is not an "every ms" issue, more an "multiple GC runs needed to get rid of the objects.
Finalize is conceptually different than Dispose. Finalize can only free unmanaged resources. Dispose can free managed and unmanaged resources. You should use each as appropriate. (Note that a class with a Finalizer should always implement IDisposable).
Dispose must be called explicitly; Finalize can only be called by the GC.
Update: See my blog post on How to Implement IDisposable and Finalizers: 3 Easy Rules.
I've got a blog post about IDisposable and Finalizing - not about the performance though.
I'll answer your second question.
No, Finalize should not be used in this manner. In fact, with the exception of only a very few fringe cases, you should only override Finalize (or declare a destructor in C#) if the class directly holds unmanaged resources.
The issue you described is one of ownership. The owner of an IDisposable class is responsible for its lifetime and the decision of when to call Dispose. Other parts of code are free to use that class, but since they cannot claim ownership they should not participate in the lifetime management of that class.
Unfortunately I am not very familiar with the Font class nor how it might relate to the specific scenario that was the impetus for your question, but I can make a general statement that might apply to you. If your code did not create the instance (via the constructor) directly then your code should not be considered the owner. In that case you can assume the responsibility for disposal is left to something else.
Finalize is extremely useful as a double check. If a crash or someone's bad code doesn't dispose your object before it goes out of scope, guarantee that its resources will be released in the finalizer.
You can do some fancy footwork in your disposer though by calling GC.SuppressFinalize(this) which will allow you to write a method which will work in both situations and give you a guarantee that the code will work nicely.
You could even fire an MDA if you were writing a framework to remind people that they should dispose your object.
The penalty of the finalizer is basically that you end up pushing your object into the level 2 queue which takes longer to run. If you are consistently using objects and they are finalizing this could result in a level 2 collection running more often than neccessary just to run your finalizer threads.
When you create and use a Web Service proxy class in the ASP.Net framework, the class ultimately inherits from Component, which implements IDisposable.
I have never seen one example online where people dispose of a web proxy class, but was wondering if it really needs to be done. When I call only one method, I normally wrap it in a using statement, but if I have a need to call it several times throughout the page, I might end up using the same instance, and just wondered what the ramifications are of not disposing it.
You need to dispose everything that implements IDisposable.
The implementation of IDisposable signifies that the object holds onto something that the garbage collector doesn't intrinsically track - might be a connection, might be a file, might be some other handle - or might be nothing at all, it doesn't really matter. You shouldn't concern yourself with the implementation details because those are subject to change.
The class may or may not truly use unmanaged resources. It may or may not have a finalizer. It makes little difference; if the class implements IDisposable, then it's asking you to Dispose it when you're done. Even if the Dispose method does nothing, you never know when somebody will replace the reference to that class with a reference to a subclass that really does need to be disposed.
The short answer is that with Web Service Proxy Classes, you should Close them and not Dispose them.
In almost every case you should dispose of things that implement IDisposable. However, Web Service Proxy classes are a special case. With these classes, and all classes that inherit from System.ServiceModel.ClientBase, it is a best practice to not call dispose but to call the Close method directly.
Using reflector, you can see that the Dispose method of ClientBase simply calls Close. So if there are no exceptions, Dispose and Close will do the same thing. However if there is an exception, there will be different behaviors.
Because the Close method can throw exceptions, you should call it directly and catch it's exception. If you call the Dispose method, you should also catch the exceptions, but your code will be harder to understand.
This also means that you should avoid putting the declaration of the proxy in a using statement. In this case, if an exception is thrown in the using block, it will be obscured. The Dispose call that is auto generated by the using block will get called because it is in a finally block. The exception that is thrown from the Close in the Dispose will obscure whatever exception was previously thrown.
To see more detailed explinations, read these articles on MSDN, Coding Up Style, BlogginAbout.Net, and StackOverflow.
For the backstory on why it is implemented this way, check on this thread on the MSDN forums.
Sometimes Dispose() is just a dummy (inherited from a base class), but then it is still a good practice to call it, to be safe for future changes.
A WebService/WCF proxy is holding a connection, so it is certainly a good idea to call Dispose() or Close(). Doing so inside a using block is of course preferable since it is exception safe.
But in your case (using the proxy in multiple methods on your page) the use of multiple using blocks probably would take a performance hit. It is OK to replace the using blocks with a call Close() in an event that comes late in the page cycle. I'm not sure about ASP.NET best practices here, but I would use OnPreRender or OnPageUnload or something.
You will loose exception safety here but that is not a fundamental problem, the GC will solve that.
IMHO, there's nothing like disposing a web-service proxy class.
Most of the proxies are:
Stateless, as such calling using one instance or using multiple instances does not make any difference
Intermittent meaning that they close the connection as soon as all response is processed
This is what I understand about IDisposable and finalizers from "CLR via C#", "Effective C#" and other resources:
IDisposable is for cleaning up managed and unmanaged resources deterministically.
Classes that are responsible for unmanaged resources (e.g. file handles) should implement IDisposable and provide a finalizer to guarantee that they are cleaned up even if the client code does not call Dispose() on the instance.
Classes that are responsible for managed resources only should never implement a finalizer.
If you have a finalizer then you must implement IDisposable (this allows client code to do the right thing and call Dispose(), while the finalizer prevents leaking resources if they forget).
While I understand the reasoning for and agree with all of the above, there is one scenario where I think it makes sense to break these rules: a singleton class that is responsible for unmanaged resources (such as providing a single point of access to particular files).
I believe it is always wrong to have a Dispose() method on a singleton because the singleton instance should live for the life of the application and if any client code calls Dispose() then you are stuffed. However, you want a finalizer so that when the application is unloaded the finalizer can clean up the unmanaged resources.
So having a singleton class with a finalizer that does not implement IDisposable seems to me to be a reasonable thing to do, yet this type of design is counter to what I understand are best practices.
Is this a reasonable approach? If not, why not and what are the superior alternatives?
I'd first mention that Object Oriented design patterns and their consequences do not always influence every language decision, even in Object Oriented languages. You can certainly find classic design patterns that are easier to implement in one language (Smalltalk) as opposed to another (C++).
That being said, I'm not sure I agree with the premise that a singleton instance should only be disposed at the end of an application. Nothing in the design pattern descriptions that I've read for Singleton (or Design Patterns: Elements of reusable Object-Oriented Software) mention this as a property of this pattern. A singleton should ensure that only one instance of the class exists at any one moment in time; that does not imply that it must exist for as long as the application exists.
I have a feeling that in practice, many singletons do exist for most of the life of an application. However, consider an application that uses a TCP connection to communicate with a server, but can also exist in a disconnected mode. When connected, you would want a singleton to maintain the connection information and state of the connection. Once disconnected, you may want to keep that same singleton - or you may dispose of the singleton. While some may argue that it makes more sense to keep the singleton (and I may even be among them), there is nothing in the design pattern itself that precludes you from disposing of it - if a connection is remade, the singleton can be instantiated again, as no instance of it exists at that moment in time.
In other words, you can create scenarios where it is logical for singletons to have IDisposable.
If the unmanaged resource is released only on application exit you don't even need to worry with a finalizer since the process unload should deal with this for you anyway.
If you have multiple app domains and you want to deal with an app domain unload that's one possible issue but possibly one you don't need to care about.
I second those saying that this design is possibly not the right thing to do (and will make it harder to fix is subsequently you find that you do actually need two instances)
Create the object (or a lazy loading wrapper object) in your entry point and pass it through the code to where it is needed making it clear who is responsible for providing it to whom, then you are free to change the decision to use only one with little effect to the rest of the code (which uses what it gets given)
As long as your finalizer doesn't call methods (such as Dispose) on any other managed objects, you should be fine. Just remember that finalization order is not deterministic. That is, if your singleton object Foo holds a reference to object Bar that requires disposal, you cannot reliably write:
~Foo()
{
Bar.Dispose();
}
The garbage collector might have collected Bar already.
At the risk of stepping into a pile of OO goo (i.e. starting a war), one alternative to using a singleton is to use a static class.
While it may get you code review gripes and FxCop warnings, there's nothing intrinsically wrong with implementing a finalizer without IDisposable. However, doing so on a singleton is not a reliable way to capture process or AppDomain tear-down.
At the risk of offering subjective design advice: If the object is truly stateless, make it a static class. If it is stateful, question why it is a Singleton: you're creating a mutable global variable. If you're trying to capture application close, deal with it when your main loop exits.
Applicability of Singleton to any particular situation aside,
I think there is nothing wrong with Disposing of Singleton. In combination with lazy instantiation it just means that you release resource if you do not need it temporarily, and then re-acquire it as needed.
If you want to create a singleton with a finalizer, you should probably have the static reference to it be a WeakReference. This will require a little bit of extra work to ensure thread-safety in the accessor, but it will allow the singleton to be garbage-collected when nobody is using it (if someone subsequently calls the GetInstance() method, they'll get a new instance). If a static strong reference were used, it would keep the singleton instance alive even if there were no other references to it.