I understand what the using clause does, but should it be used with unnamed parameters?
For example; should:
var navigator = new XPathDocument(new StringReader(request)).CreateNavigator();
be:
using (StringReader sr = new StringReader(request))
{
var navigator = new XPathDocument(sr).CreateNavigator();
...
}
It makes no difference whether you are assigning the object implementing IDisposable to a variable, you should still be disposing it and hence you should use Using.
Best way to know how it works : test!
class Program
{
public static void Main()
{
using (TestDisposable d = new TestDisposable())
{
} // Will trace "disposed"
UseDisposable use = UseDisposable.Create(new TestDisposable());
// Will trace "disposed"
}
}
public class UseDisposable
{
public TestDisposable Disposable;
public static UseDisposable Create(TestDisposable disposable)
{
return new UseDisposable()
{
Disposable = disposable
};
}
}
public class TestDisposable : IDisposable
{
private bool _disposed = false;
#region IDisposable Membres
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if(!_disposed && disposing)
{
Trace.WriteLine("Disposed");
_disposed = true;
}
}
#endregion
}
In my opinion, you should always use the second method.
Your first code piece is equivalent to this:
StringReader sr = new StringReader(request);
var navigator = new XPathDocument(sr).CreateNavigator();
The difference is that you dont create an explicit "handle" for your StringReader and therefore lose the ability to work with it later on (e.g.: disposing it).
Therefore you should be using the "using" clause. It also enhances the readability.
Yes you should use this if you can. I think the MS code analysis even warns you if you don't.
Related
The Disposable pattern is one that is re-implemented on a per class basis. So, I was looking for a way to generalize it. The problem I ran into a few years ago is that, even if you implement it as class itself, you can't have an object derive from both your Disposable implementation and from another class (C# doesn't support multi-inheritance).
The question is, how do you make a generic way to have the Disposable pattern implemented so you don't need to write it explicitly per class that implements IDisposable?
Here is the standard Disposable pattern that is generated for you by Visual Studio (VS 2015).
public class TestClass : IDisposable {
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing) {
if (!disposedValue) {
if (disposing) {
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~DisposeTest() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose() {
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
My implementation
So, here is the solution I came up with.
public class DisposeService<T> where T : IDisposable {
private readonly T _disposee;
public Action<T> ManagedAction { get; set; }
public Action<T> UnmanagedAction { get; set; }
public DisposeService(T disposee, Action<T> managedAction = null, Action<T> unmanagedAction = null) {
_disposee = disposee;
ManagedAction = managedAction;
UnmanagedAction = unmanagedAction;
}
private bool _isDisposed;
public void Dispose(bool isDisposing) {
if (_isDisposed) return;
if (isDisposing && ManagedAction != null) {
ManagedAction(_disposee);
}
var hasUnmanagedAction = UnmanagedAction != null;
if (hasUnmanagedAction) {
UnmanagedAction(_disposee);
}
_isDisposed = true;
if (isDisposing && hasUnmanagedAction) {
GC.SuppressFinalize(_disposee);
}
}
}
This class allows you to create a DisposableService<> member for your class that implements IDisposable. Here is an example on how to use it when you only have managed resources.
public class TestClass : IDisposable {
protected readonly DisposeService<TestClass> DisposeService;
private readonly SafeHandle _handle;
public TestClass() {
DisposeService = new DisposeService<TestClass>(this, ps => { if (_handle != null) _handle.Dispose(); });
_handle = new SafeFileHandle(IntPtr.Zero, true);
}
public void Dispose() {
DisposeService.Dispose(true);
}
}
How it works
The DisposeService will run it's Dispose on your object's Dispose.
The DisposeService's dispose will run your Managed and Unmanaged Action that you provide on initialization (or update in derived classes).
The GC.SuppressFinalize will run automatically if an UnmanagedAction is provided.
Always make sure to create the DisposableService<> as the first action of your constructor.
So, here is an example of using this service with unmanaged resources.
public class TestClass : IDisposable {
protected readonly DisposeService<TestClass> DisposeService;
private readonly SafeHandle _handle;
public TestClass() {
DisposeService = new DisposeService<TestClass>(this,
ps => { if (_handle != null) _handle.Dispose(); },
ps => { /* Free unmanaged resources here */ });
_handle = new SafeFileHandle(IntPtr.Zero, true);
}
public void Dispose() {
DisposeService.Dispose(true);
}
~TestClass() {
DisposeService.Dispose(false);
}
}
And, an example of making a derived class from the class above.
public class TestClassDerived : TestClass, IDisposable {
private readonly SafeHandle _derivedHandle;
public TestClassDerived() {
// Copy the delegate for the base's managed dispose action.
var baseAction = DisposeService.ManagedAction;
// Update the managed action with new disposes, while still calling the base's disposes.
DisposeService.ManagedAction = ps => {
if (_derivedHandle != null) {
_derivedHandle.Dispose();
}
baseAction(ps);
};
_derivedHandle = new SafeFileHandle(IntPtr.Zero, true);
}
}
Easy peasy lemon squeezy. You keep the reference to the base's delegate and call it as part of the derived class's delegate.
Overall, should be cleaner then managing that procedural region of blarg that Microsoft has been providing since 2005...
Edit: I thought the 'this' being passed in the constructor might be a concern. But, it doesn't seem to be: Is it a bad practice to pass "this" as an argument? Just remember to put the null checks in your actions so you don't try to Dispose something that is null. :-)
I application that uses a a Interop Com Object. Therefore I had written a wrapper class, to do the freeing in the dispose or if this is not done in the finalizer. So I can use the using keyword, to ensure a freeing is done.
Is using this pattern a good way? Or is there even a class in the Framework that is doing this for me?
class ComWrapper<T> : IDisposable
{
private readonly T comObject;
private bool disposed = false;
public ComWrapper(T comObject)
{
this.comObject = comObject;
}
~ComWrapper()
{
this.Dispose(false);
}
public T ComObject
{
get
{
return this.comObject;
}
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (this.disposed)
{
return;
}
Marshal.FinalReleaseComObject(this.comObject);
}
}
I personally wouldn't recommend this because it seems somewhat pointless. But, I would recommend having a static class called Utility, with this method:
public static void disposeComObject<T>(ref T comObject)
{
if(Marshal.IsComObject(comObject) && comObject != null)
{
//You need to save the object
if(typeof(T) == typeof(Microsoft.Office.Interop.Excel.Workbook))
{
((Microsoft.Office.Interop.Excel.Workbook))comObject.Save();
((Microsoft.Office.Interop.Excel.Workbook))comObject.Close();
}
//You need to save the object
if(typeof(T) == typeof(Microsoft.Office.Interop.Excel.Application))
{
((Microsoft.Office.Interop.Excel.Application))comObject.Quit();
}
Marshal.ReleaseComObject(comObject);
comObject = null;
}
}
Now From Code, you can call this like so
...
Microsoft.Office.Interop.Excel comObject = null;
try{
//Open comObject
//Here I would call some functions, and have nested exceptions
}
catch(nestedException err)
{
//Handle at your discretion
}
finally{
Utility.disposeComObject(ref comObject);
}
This is specific to the Excel Namespace, but adjusting it should be easy enough.
Is there a built-in ThreadLocal<T>-like construct for sharing an object within each unique thread but recreating it if the original value was disposed/destructed/teared down/nulled?
Here's my attempt at implementing such behaviour with ConcurrentDictionary (the ThreadLocalDisposable2 below), but I was hoping to just use ThreadLocal<T> (as in ThreadLocalDisposable1), however I can't get the Foo test to pass, .Values.Remove(this) doesn't do what I was hoping it would do and still causes ObjectDisposedException.
public class Class1
{
[Test]
public void Foo()
{
using (var foo = ThreadLocalDisposable1.Get())
foo.Foo();
using (var foo = ThreadLocalDisposable1.Get())
foo.Foo();
}
[Test]
public void Bar()
{
using (var bar = ThreadLocalDisposable2.Get())
bar.Foo();
using (var bar = ThreadLocalDisposable2.Get())
bar.Foo();
}
}
[1]
public class ThreadLocalDisposable1 : IDisposable
{
private Stream _foo;
private static ThreadLocal<ThreadLocalDisposable1> _thread;
static ThreadLocalDisposable1()
{
_thread = new ThreadLocal<ThreadLocalDisposable1>(() => new ThreadLocalDisposable1(), true);
}
private ThreadLocalDisposable1()
{
_foo = new MemoryStream();
}
public static ThreadLocalDisposable1 Get()
{
return _thread.Value;
}
public void Foo()
{
_foo.WriteByte(1);
}
public void Dispose()
{
//I do not think it means what I think it means
_thread.Values.Remove(this);
_foo.Dispose();
}
}
[2]
public class ThreadLocalDisposable2 : IDisposable
{
private Stream _foo;
private int _thread;
private static ConcurrentDictionary<int, ThreadLocalDisposable2> _threads;
static ThreadLocalDisposable2()
{
_threads = new ConcurrentDictionary<int, ThreadLocalDisposable2>();
}
private ThreadLocalDisposable2(int thread)
{
_thread = thread;
_foo = new MemoryStream();
}
public static ThreadLocalDisposable2 Get()
{
return _threads.GetOrAdd(Thread.CurrentThread.ManagedThreadId, i => new ThreadLocalDisposable2(i));
}
public void Foo()
{
_foo.WriteByte(1);
}
public void Dispose()
{
ThreadLocalDisposable2 thread;
_threads.TryRemove(_thread, out thread);
_foo.Dispose();
}
}
Edit:
Just to clarify what I mean, basically I want all of the behaviour of ThreadLocal but when I call Dispose (on the value, the ThreadLocalDisposable* with underlying Stream in this example, not the static ThreadLocal itself) take that disposed instance out of circulation, i.e. if called upon again -- create a new value as if it's a brand new thread requiring a brand new instance.
The ThreadLocalDisposable1, [1], is sample class of what I think should've worked, except the .Values.Remove(this) line doesn't "take it out of circulation" and forces a new instance to be created for that thread.
The ThreadLocalDisposable2, [2], with ConcurrentDictionary, is a way I implemented alternative to ThreadLocal with "take out of circulation" behaviour I'm after.
Edit:
This is not the a real use case I have, just a general example I can think of, but if you have for example a static ThreadLocal<SqlConnection>, or a socket, and it's forcefully closed (and disposed in final block) -- drop that connection instance and create a new one transparently if called again.
It seems like you're making this much harder than it has to be. Consider this:
public class MyClass: IDisposable
{
private Stream _foo;
public MyClass Get()
{
if (_foo == null)
{
_foo = new MemoryStream();
}
}
public void Foo()
{
_foo.WriteByte(1);
}
public void Dispose()
{
if (_foo != null)
{
_foo.Dispose();
_foo = null;
}
}
}
Now, you can create one of those:
ThreadLocal<MyClass> MyThing = new ThreadLocal<MyClass>();
And you can write:
using (MyThing.Value.Get())
{
// do stuff
}
That seems functionally equivalent to what you're trying to do with your ConcurrentDictionary stuff.
That said, it seems like this is something that would be better managed another way. I don't know your application so I can't say for sure, but it seems like a bad idea to have a stateful object like a Stream or SqlConnection as a global variable. Usually those things are job-specific rather than thread-specific, and as such should be passed as parameters when you start the job.
Hi I have code here where I don't understand why I hit the breakpoint (see comment).
Is this a Microsoft bug of something I don't know or I don't understand properly ?
The code was tested in Debug but I think it should not changes anything.
Note: You can test the code directly in a console app.
JUST FOR INFORMATION... following supercat answer, I fixed my code with proposed solution and it works nicely :-) !!! The bad thing is the usage of a static dict and the performance the goes with it but it works.
... After few minutes, I realized that SuperCat give me all hints to do it better, to workaround the static dictionary and I did it. Code samples are:
Code with the bug
Code corrected but with a static ConditionalWeakTable
Code with ConditioalWeakTable that include the SuperCat tricks (thanks so much to him !)
Samples...
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace WeakrefBug
{
// **********************************************************************
class B : IDisposable
{
public static List<B> AllBs = new List<B>();
public B()
{
AllBs.Add(this);
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
AllBs.Remove(this);
disposed = true;
}
}
~B() { Dispose(false); }
}
// **********************************************************************
class A
{
WeakReference _weakB = new WeakReference(new B());
~A()
{
B b = _weakB.Target as B;
if (b == null)
{
if (B.AllBs.Count == 1)
{
Debugger.Break(); // b Is still referenced but my weak reference can't find it, why ?
}
}
else { b.Dispose(); }
}
}
// **********************************************************************
class Program
{
static void Main(string[] args)
{
A a = new A();
a = null;
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
}
}
// **********************************************************************
}
Version corrected:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace WeakrefBug // Working fine with ConditionalWeakTable
{
// **********************************************************************
class B : IDisposable
{
public static List<B> AllBs = new List<B>();
public B()
{
AllBs.Add(this);
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
AllBs.Remove(this);
disposed = true;
}
}
~B() { Dispose(false); }
}
// **********************************************************************
class A
{
private static readonly System.Runtime.CompilerServices.ConditionalWeakTable<A, B> WeakBs = new ConditionalWeakTable<A, B>();
public A()
{
WeakBs.Add(this, new B());
}
public B CreateNewB()
{
B b = new B();
WeakBs.Remove(this);
WeakBs.Add(this, b);
return b;
}
~A()
{
B b;
WeakBs.TryGetValue(this, out b);
if (b == null)
{
if (B.AllBs.Count == 1)
{
Debugger.Break(); // B Is still referenced but my weak reference can't find it, why ?
}
}
else { b.Dispose(); }
}
}
// **********************************************************************
class Program
{
static void Main(string[] args)
{
A a = new A();
WeakReference weakB = new WeakReference(a.CreateNewB()); // Usually don't need the internal value, but only to ensure proper functionnality
a = null;
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
Debug.Assert(!weakB.IsAlive);
}
}
// **********************************************************************
}
Code with ConditioalWeakTable that include the SuperCat tricks (thanks so much to him !)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace WeakrefBug // Working fine with non static ConditionalWeakTable - auto cleanup
{
// **********************************************************************
class B : IDisposable
{
public static List<B> AllBs = new List<B>();
public B()
{
AllBs.Add(this);
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
AllBs.Remove(this);
disposed = true;
}
}
~B() { Dispose(false); }
}
// **********************************************************************
class A
{
private ConditionalWeakTable<object, object> _weakBs = null;
public A()
{
}
public B CreateNewB()
{
B b = new B();
if (_weakBs == null)
{
_weakBs = new ConditionalWeakTable<object, object>();
_weakBs.Add(b, _weakBs);
}
_weakBs.Remove(this);
_weakBs.Add(this, b);
return b;
}
internal ConditionalWeakTable<object, object> ConditionalWeakTable // TestOnly
{
get { return _weakBs; }
}
~A()
{
object objB;
_weakBs.TryGetValue(this, out objB);
if (objB == null)
{
if (B.AllBs.Count == 1)
{
Debugger.Break(); // B Is still referenced but my weak reference can't find it, why ?
}
}
else
{
((B)objB).Dispose();
}
}
}
// **********************************************************************
class Program
{
static void Main(string[] args)
{
A a = new A();
WeakReference weakB = new WeakReference(a.CreateNewB()); // Usually don't need the internal value, but only to ensure proper functionnality
WeakReference weakConditionalWeakTable = new WeakReference(a.ConditionalWeakTable);
a = null;
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
Debug.Assert(!weakB.IsAlive);
Debug.Assert(!weakConditionalWeakTable.IsAlive);
}
}
// **********************************************************************
}
Following question of CitizenInsane...
I don't remember exactly why I did what I did... I found my sample but wasn't sure about my intention at that time. I tried to figure it out and came with the following code which I thing is more clear but still don't remember my original need. Sorry ???
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace WeakrefBug // Working fine with ConditionalWeakTable
{
// **********************************************************************
class B : IDisposable
{
public static List<B> AllBs = new List<B>();
public B()
{
AllBs.Add(this);
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
AllBs.Remove(this);
disposed = true;
}
}
~B() { Dispose(false); }
}
// **********************************************************************
class A
{
private ConditionalWeakTable<object, object> _weakBs = null;
private WeakReference _weakB = null;
public A()
{
_weakBs = new ConditionalWeakTable<object, object>();
B b = new B();
_weakB = new WeakReference(b);
_weakBs.Add(b, _weakB);
}
public B B
{
get
{
return _weakB.Target as B;
}
set { _weakB.Target = value; }
}
internal ConditionalWeakTable<object, object> ConditionalWeakTable // TestOnly
{
get { return _weakBs; }
}
~A()
{
B objB = B;
if (objB == null)
{
if (B.AllBs.Count == 1)
{
Debugger.Break(); // B Is still referenced but my weak reference can't find it, why ?
}
}
else
{
((B)objB).Dispose();
}
}
}
// **********************************************************************
class Program
{
static void Main(string[] args)
{
Test1();
Test2();
}
private static void Test1()
{
A a = new A();
WeakReference weakB = new WeakReference(a.B); // Usually don't need the internal value, but only to ensure proper functionnality
WeakReference weakConditionalWeakTable = new WeakReference(a.ConditionalWeakTable);
a = null;
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
Debug.Assert(B.AllBs.Count == 0);
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
Debug.Assert(!weakB.IsAlive); // Need second pass of Collection to be collected
Debug.Assert(!weakConditionalWeakTable.IsAlive);
}
private static void Test2()
{
A a = new A();
WeakReference weakB = new WeakReference(a.B);
B.AllBs.Clear();
a.B = null;
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
Debug.Assert(!weakB.IsAlive); // Need second pass of Collection to be collected
}
}
// **********************************************************************
}
A sometimes-irksome limitation of WeakReference is that a WeakReference may be invalidated if no strongly-rooted reference exists to the WeakReference itself, and this may occur even if the trackResurrection constructor parameter was true, and even if the target of the WeakReference is strongly rooted. This behavior stems from the fact that a WeakReference has an unmanaged resource (a GC handle) and if the finalizer for the WeakReference didn't clean up the GC handle, it would never get cleaned up and would constitute a memory leak.
If it will be necessary for an object's finalizers to make use of WeakReference objects, the object must make some provision to ensure that those objects remain strongly referenced. I'm not sure what the best pattern is to accomplish this, but the ConditionalWeakTable<TKey,TValue> that was added in .net 4.0 may be useful. It's a little bit like Dictionary<TKey,TValue> except that as long as a table itself is strongly referenced and a given key is strongly referenced, its corresponding value will be regarded as strongly referenced. Note that if a ConditionalWeakTable holds an entry linking X to Y, and Y to the table, then as long as X or Y remains, the table will remain as well.
There are two aspects of garbage collection that you didn't count on:
The exact time at which the WeakReference.IsAlive becomes false. Your code implicitly assumes that will happen when the finalizer runs. This is not the case, it happens when the object gets garbage collected. After which the object is placed on the finalizer queue, because it has a finalizer and GC.SuppressFinalize() wasn't called, waiting for the finalizer thread to do its job. So there's a period of time where IsAlive is false but ~B() hasn't run yet.
The order in which objects get finalized is not predictable. You implicitly assume that B is finalized before A. You cannot make this assumption.
There's also a bug in the B.Dispose() method, it won't correctly count B instances when the client code explicitly disposed the object. You haven't hit that bug yet.
There is no reasonable way to fix this code. Moreover, it tests something that is already backed by hard guarantees provided by the CLR. Just remove it.
The WeakReference _weakB is available for garbage collection at the same time as the object a is. You don't have a guarantee of order here, so it could very well be that _weakB is finalized before object a.
Accessing _weakB in the finalizer of A is dangerous, since you don't know the state of _weakB. I'm guessing that in your case it has been finalized, and that that is causing it to return null for .Target.
Create class MustDispose.cs
public class MustDispose
{
public MustDispose()
{
}
}
in.aspx Page
protected void Page_Load(object sender, EventArgs e)
{
using (MustDispose obj = new MustDispose)
{
// use the object
}
}
errorr
Destructors and object.Finalize cannot be called directly. Consider
calling IDisposable.Dispose if available.
You class has to impplement IDisposable, in oder to be used inside using statement.
Example:
public class MustDispose : IDisposable
{
public MustDispose()
{
}
//implement Dispose
public void Dispose()
{
....
}
}
reading from using:
Provides a convenient syntax that ensures the correct use of
IDisposable objects.
You need to implement IDisposable like so:
class TestDispose : IDisposable
{
public TestDispose()
{
...
}
public void Dispose()
{
// dispose of your resources here
}
}
Then you will be able to use it in a using block which automatically calls obj.Dispose at the end of the block.
using (var obj = new TestDispose())
{
...
}
Is like:
var obj = new TestDispose();
try
{
...
}
finally
{
obj.Dispose();
}