I asked a question earlier today, but I think I need to approach it in a different way (on top of that there was a "hang up" in regards to DataSet).
Here's a class that encapsulates the creation of a Font (in other words, it is reading data from an xml file and is creating a font, at runtime, based on what it reads from that file):
public class FontCreator
{
private Font m_TheFont = null;
public FontCreator( ... some parameters ... )
{
m_TheFont = GetTheFont();
}
public Font TheFont
{
return m_TheFont;
}
private Font GetTheFont()
{
// code, and more code, that eventually leads to:
Font f = new Font(fntFamily, fntSize, fntStyle);
return f;
}
}
The consumer of the FontCreator class looks something like:
public class TheConsumer()
{
private FontCreator m_FontCreator = null;
public TheConsumer()
{
m_FontCreator = new m_FontCreator( ... some parameters ... );
Initialize();
}
private void Initialize()
{
InitializeThis();
InitializeThat();
}
private void InitializeThis()
{
.... some code ...
SomeObject.ApplyFont(m_FontCreator.TheFont);
}
private void InitializeThat()
{
... some code ...
SomeObject.ApplyFont(m_FontCreator.TheFont);
}
}
What code do you add, and where, to ensure that "TheFont"'s Dispose method is explicitly called?
If you don't wish to maintain a reference to TheFont after it is initially used, then call it's Dispose method in your constructor, right after Initialize. If you wish to keep TheConsumer alive for a while and maintain a reference to TheFont, it gets more interesting. Two Options:
You can have TheFont's dispose method called from the Destructor of the TheConsumer object. This is not the common practice and has problems. Mainly, this is not called until garbage collection happens. Better is:
You can make the TheConsumer object itself implement IDisposable, and call TheFont.Dispose from TheConsumer.Dispose. Since TheConsumer implements IDisposable, the code that uses it should call its Dispose method.
Edit in response to harsh comment!
Yes, I should have made clear to only use 1 in addition to 2, if at all. I know all developers everywhere are supposed to notice when IDisposable is implemented, but they often don't. If the referenced managed resource might really remain around a long time and cause problems if not properly disposed, I sometimes have a safety Dispose() method call in the destructor of the object holding the reference. Is that so wrong? :)
public TheConsumer()
{
using (m_FontCreator = new m_FontCreator( ... some parameters ... ))
{
Initialize();
}
}
I am confused, if you want to quickly use the font creater object then implement IDisposable on the FontCreater and use
using(m_FontCreator = new FontCreater(....))
{
InitializeThis();
InitializeThat();
}
If you need to keep the instance of the FontCreater through the lifetime of TheConsumer, then implement IDisposable on both FontCreater and TheConsumer classes.
public class TheConsumer : IDisposable
{
void Dispose()
{
if(m_FontCreator != null)
m_FontCreator.Dispose();
}
}
then use TheConsumer class like so
using(TheConsumer consumer = new TheConsumer(....))
{
....
}
Answer 1: Avoid it. Don't keep objectsthat contain unmanaged resources around any longer than necessary.
Answer 2: If you do need the embedded fields as shown in your code, than both the FontCreator and the Consumer class need to implement IDisposable. But not a destructor (Finalizer).
The main argument for this is that FontCreator is the 'owner' of the Font and should therefore take responsibility. And the Consumer is responsible for the Creator in the same way.
As others have noted, it appears you can at least avoid the m_FontCreator field in the Consumer class. But it depends on the rest of the code, is m_FontCreator used elsewhere?
Related
Till today I was thinking that members of reachable objects are also considered to be reachable.
But, today I found one behavior which creates a problem for us either when Optimize Code is checked or application is executed in Release Mode. It is clear that, release mode comes down to the code optimization as well. So, it seems code optimization is reason for this behavior.
Let's take a look to that code:
public class Demo
{
public Action myDelWithMethod = null;
public Demo()
{
myDelWithMethod = new Action(Method);
// ... Pass it to unmanaged library, which will save that delegate and execute during some lifetime
// Check whether object is alive or not after GC
var reference = new WeakReference(myDelWithMethod, false);
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
Console.WriteLine(reference.IsAlive);
// end - Check whether object is alive or not after GC
}
private void Method() { }
}
I simplified code a bit. Actually, we are using our special delegate, not Action. But the behavior is same. This code is written in mind with "members of reachable objects are also considered to be reachable". But, that delegate will be collected by GC asap. And we have to pass it to some unmanaged library, which will use it for some time.
You can test demo by just adding that line to the Main method:
var p = new Demo();
I can understand the reason of that optimization, but what is the recommended way to prevent such case without creating another function which will use that variable myDelWithMethod which will be called from some place? One, option I found that, it will work if I will set myDelWithMethod in the constructor like so:
myDelWithMethod = () => { };
Then, it won't be collected until owning instance is collected. It seems it can't optimize code in the same way, if lambda expression is setted as a value.
So, will be happy to hear your thoughts. Here are my questions:
Is it right that, members of reachable objects are also considered to
be reachable?
Why it is not collected in case of lambda expression?
Any recommended ways to prevent collection in such cases?
However strange this would sound, JIT is able to treat an object as unreachable even if the object's instance method is being executed - including constructors.
An example would be the following code:
static void Main(string[] args)
{
SomeClass sc = new SomeClass() { Field = new Random().Next() };
sc.DoSomethingElse();
}
class SomeClass
{
public int Field;
public void DoSomethingElse()
{
Console.WriteLine(this.Field.ToString());
// LINE 2: further code, possibly triggering GC
Console.WriteLine("Am I dead?");
}
~SomeClass()
{
Console.WriteLine("Killing...");
}
}
that may print:
615323
Killing...
Am I dead?
This is because of inlining and Eager Root Collection technique - DoSomethingElse method do not use any SomeClass fields, so SomeClass instance is no longer needed after LINE 2.
This happens to code in your constructor. After // ... Pass it to unmanaged library line your Demo instance becomes unreachable, thus its field myDelWithMethod. This answers the first question.
The case of empty lamba expression is different because in such case this lambda is cached in a static field, always reachable:
public class Demo
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Action <>9__1_0;
internal void <.ctor>b__1_0()
{
}
}
public Action myDelWithMethod;
public Demo()
{
myDelWithMethod = (<>c.<>9__1_0 ?? (<>c.<>9__1_0 = new Action(<>c.<>9.<.ctor>b__1_0)));
}
}
Regarding recommended ways in such scenarios, you need to make sure Demo has lifetime long enough to cover all unmanaged code execution. This really depends on your code architecture. You may make Demo static, or use it in a controlled scope related to the unmanaged code scope. It really depends.
[There is a similar question Shared ownership of IDisposable objects in C# but the accepted answer suffers from similar design problems which my solution has]
I have been trying to think around this problem having seen many designs taking a blind leap of faith in garbage collector when working in c#. Reason being many times its easy to ignore that one need to handle the IDisposable rather carefully making them close equivalent of resource allocation in c++. I understand that pedantically speaking Dispose is not the equivalent of c++ destructor but if you are holding on to native resources which needs to be cleaned in a deterministic manner it becomes very similar.
But if the object is shared by multiple resources (for eg. an HttpClient object which is meant to be created and used concurrently for performance), who owns the responsibility of calling Dispose since there is no single owner? To solve this problem I came up with a SharedOwner library which has a similar interface as shared_ptr.
Code snippet:
SharedOwner:
public static SharedHandle<T> MakeSharedHandle(Func<T> createSharedOwner)
{
var obj = new SharedHandle<T>(createSharedOwner());
return obj;
}
public SharedHandle(T obj)
{
AddReference();
m_object = obj;
}
public Handle<T> GetHandle()
{
AddReference();
return new Handle<T>(this);
}
internal void Decrement()
{
if (Interlocked.Decrement(ref m_refCounter) == 0)
{
m_object.Dispose();
m_object = default(T);
}
}
internal T GetInternalHandler() { return m_object; }
private void AddReference()
{
Interlocked.Increment(ref m_refCounter);
}
~SharedHandle()
{
m_object.Dispose();
}
Handle
is a transparent wrapper that manages the ref counting calls keeping that abstracted from consumers.
public sealed class Handle<T> : IDisposable where T : IDisposable
{
private SharedHandle<T> m_handle;
bool disposed = false;
internal Handle(SharedHandle<T> handle) { m_handle = handle; }
public void Dispose()
{
if (!disposed)
{
m_handle.Decrement();
GC.SuppressFinalize(this);
disposed = true;
}
}
~Handle()
{
if (!disposed)
{
m_handle.Decrement();
}
}
The typical usage pattern that I imagined would be:
using (var sharedClient = this.m_sharedClient.GetHandle()) // m_sharedClient is the SharedHandle passed
{
var httpClient = (HttpClient)sharedClient;
// use httpClient
}
Now I see two issues with this approach which deviate it from the original motivation of simulating shared_ptr behavior:
The first reference is held by SharedHandle itself. So even when all Handles are out of scope one reference would still be held by SharedHandle thereby making the if block in Decrement unreachable.
The final Dispose happens when the SharedHandle dies which in lot of sense is no better than not calling Dispose on the underlying object itself. Hence making the solution much less valuable.
I am thinking of moving the reference counting to Handle and using SharedHandle as the control block in shared_ptr but then that means that one may end up with a valid SharedHandle object holding on to a Disposed internal object.
Another alternative that I can think of is making SharedHandle derive from IDisposable and just call Decrement in Dispose. But then this brings other set of design issues. Is there anything that can be done to solve this problem in a more elegant way?
I have a class from a third-party assembly (so I can't edit it):
public class MyClass
{
private bool _loggedIn;
public void Login() {_loggedIn = true;}
public void Logout() {
if (!_loggedIn) throw new InvalidOperationException();
_loggedIn = false;
}
}
Now, suppose I have an instance of MyClass (for which I don't know _loggedIn), and I need call LogOut. Which of the following methods of avoiding a fatal exception will generally be faster? (any other method would be fine too):
To call LogOut, and if _loggedIn == false, just catch the exception
To use reflection to check that _loggedIn == true, and only call LogOut if so
It depends on the invariants you expect to see in your application.
1. If you expect to have a lot of MyClass having different state(logged in, logged off), then it is better to avoid overhead of exception (because exception is Exceptional situation) and use some specific public IsLoggedIn property (obviously to avoid Reflection) or some TryXxxxx-like methods.
And even if you can't modify the original code no one stops you from wrapping it:
public class MyWrappedClass
{
public Boolean IsLoggedIn {get; private set;}
private MyClass m_Log;
public MyWrappedClass ()
{
this.m_Log = new MyClass();
this.IsLoggedIn = false;
}
public void Log()
{
try
{
this.m_Log.LogIn();
this.IsLoggedIn = true;
}
catch
{
this.IsLoggedIn = false;
}
}
public void LogOut()
{
try
{
this.m_Log.LogOut();
this.IsLoggedIn = false;
}
catch
{
this.IsLoggedIn = true;
}
}
}
You could even go further and implement IDisposable interface with it to avoid manual LogIn-LogOut management:
public class MyWrappedClass
{
private class LogSessionToken : IDisposable
{
private MyWrappedClass parent;
public LogSessionToken (MyWrappedClass parent)
{
parent.LogIn();
}
public void Dispose()
{
parent.LogOut();
}
}
public IDisposable LogSession()
{
return new LogSessionToken (this);
}
// ...
}
And use it like
using (var logToken = wrappedInstance.LogSession)
{
// do the work.
} // No need to worry about manual LogOut
2. If you expect to use only few of MyClass in a proper fashion, then it would be a better idea to not handle exception at all - if something wrong happened then it is some programming error thus the program shall be terminated.
First, if your class doesn't expose at least a read-only property for LoggedIn, there sounds like a fairly large design flaw.
For speed, using reflection will generally be faster, particularly if you cache the FieldInfo or build a Func<bool> using System.Linq.Expressions. This is because Exceptions collect lots of debug information when thrown, including a StackTrace, which can be expensive.
As with anything, though, it is often best to test such operations, as there are sometime optimizations or other factors that may surprise you.
If the pattern if (CanFoo) Foo(); appears very much, that tends to imply very strongly that either:
A properly-written client would know when it can or cannot call Foo. The fact that a client doesn't know suggest that it's probably deficient in other ways.
The class exposing CanFoo and Foo should also expose a method which will Foo if possible and appropriate (the method should throw if unable to establish expected post-conditions, but should return silently if the post-conditions were established before the call)
In cases where a class one does not control should provide such a method but doesn't, the cleanest approach may be to write one's own wrapper method whose semantics mirror those the missing method should have had. If a later version of the class implements the missing method, changing one's code to use that implementation may be easier than refactoring lots of if (CanFoo) constructs.
BTW, I would suggest that a properly-designed class should allow calling code to indicate whether it is expecting a transition from logged-in state to logged-out state, or whether it wants to end up in logged-out state but it doesn't care how it gets there. Both kinds of semantics have perfectly legitimate uses; in cases where the first kind would be appropriate, having a LogOut method throw an exception if called on a closed session would be a good thing, but in cases where client code merely wants to ensure that it is logged out, having an EnsureLoggedOut method that could be invoked unconditionally would be cleaner than having to add extra client-side code for that purpose.
Can we use the using statement in a constructor to declare an instance of an object for later usage. For example.
public class TestClass {
private DataClassesDataContext _dataContext;
public TestClass(string connString){
using (this._dataContext = DataClassesDataContext(connString));
}
private bool someMethod(){
_dataContext.instanceMethod(); // i want to use instance methods wherever needed and define once
}
}
You must implement IDisposable yourself and call Dispose on the data context from you Dispose method.
public class TestClass : IDisposable {
private DataClassesDataContext _dataContext;
public TestClass(string connString){
_dataContext = new DataClassesDataContext(connString);
}
private bool someMethod(){
_dataContext.instanceMethod(); // i want to use instance methods wherever needed and define once
}
public void Dispose(){
_dataContext.Dispose();
}
}
It's not clear what you expect the using statement to do here. All it does is make sure that Dispose is called at the end of the block.
So basically you'd be creating a DataClassesDataContext (I assume you missed the new keyword...), storing a reference in a field, and then immediately disposing of it. That's not going to work well - you should get rid of the using statement, but quite possibly make your class implement IDisposable so that when the instance of TestClass is disposed, you dispose of the data context.
According to MSDN:
The using statement calls the Dispose method on the object in the
correct way, and (when you use it as shown earlier) it also causes the
object itself to go out of scope as soon as Dispose is called.
The using statement is basically syntactic sugar for try/finally.
try
{
_dataContext = new DataClassesDataContext(connString);
}
finally
{
if (_dataContext != null)
((IDisposable)dataContext).Dispose();
}
Looking at it in this way it should become obvious that datacontext is no longer in scope and therefore can't be used by other methods as you desire. To solve the problem, you should make the class implement IDisposeable.
using (this._dataContext = DataClassesDataContext(connString));
is the same as
try
{
this._dataContext = DataClassesDataContext(connString);
}
catch
{
}
finally
{
if(this._dataContext!=null)
((IDisposable)this._dataContext).Dispose();
}
So you'll get _dataContext disposed in you constructor and it will be no longer available. You should implement IDisposable interface and you'll be able to employ using statement where you want like this:
using (TestClass test = new TestClass("conn"))
{
//your code
}
If a class has an instance field that implements IDisposable then the containing class implements IDisposable and class that fields Dispose method from within its Dispose method.
public class A : IDisposable
{
public System.Drawing.Font font = new Font("Arial", 10.0f);
public void Dispose()
{
font.Dispose()
}
}
(I know I didn't do the dispose pattern correctly, but for sample code should be good enough)
If the field is a static field though where should the call to the field's Dispose be?
public class B
{
public static System.Drawing.Font font = new Font("Arial", 10.0f);
}
I could make class B implement IDisposable and have that call font.Dispose but if B.font is used again later on that would cause problems. As well as you'd have to remember that dispise accessing a static method you need to create an instance just to call Dispose.
I could also make a static Dispose method but then users have to remember to call Dispose and have to make sure they're the last user of it in the program.
Static fields are initialised when the type is loaded.
Therefore it logically it makes sense to dispose the object assigned to the static field when the containing type is unloaded.
However, types are not unloaded. There may be some exotic complication here around AppDomains, but I suspect that doesn't apply in your case.
Therefore I wouldn't dispose the instance, otherwise you will have a publicly available instance of an object that is unfit for use.
If the field is static, then maybe the intention is to have it last for the complete duration of the application? Because then it will only need to be disposed of when the application shuts down. And that will happen one way or the other, by itself-
If you plan to reassign the static field to different IDisposable objects several times during the lifetime of the application, then of course you would want to dispose the old object when you reassign. Maybe you could use a property for that? Not that I have thought a lot about it, but something like:
// private - don't write to this field from outside the property setter
static Font font = new Font("Arial", 10.0f));
public static Font Font
{
get
{
return font;
}
set
{
var oldFont = font;
if (oldFont != null)
oldFont.Dispose();
font = value;
}
}
You dispose of it like any other object. It doesn't make a difference. A static object is just an object that is available per class. It's still an instance of something. Granted, you probably wouldn't want to do this since after you dispose of it someone can still access it and get a ObjectDisposedException exception.
static void Main(string[] args)
{
using (Test.Instance)
{
}
Thread.Sleep(TimeSpan.FromSeconds(10));
}
public class Test:IDisposable
{
public static Test Instance = new Test();
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
And the output is:
Disposed
Per your updated example:
public class A
{
public static System.Drawing.Font font = new Font("Arial", 10.0f));
}
You can just do A.font.Dispose() or using(A.font)
In general I think the idea is you really wouldn't have a public static disposable field since by making it static you imply it should be around for the lifetime of the application. If it has to be disposable you should could make it lazy and make it be thread-safely re-initializable, otherwise accessing it after disposing will throw exceptions. Or you can have a hook into your application end code and safely dispose of all static disposables there. You can register your disposable on start somewhere as well. Just an idea
You can't dispose a static class because there is no instance of it