I'm not super handy at managing COM Objects. I've done a fair bit of reading, but I can't quite wrap my head around what happens when you have two references pointed at a single COM Object, and you release one of them. Consider the following [semi-]hypothetical:
I've created a basic wrapper class for Excel Workbooks in C#:
using ExcelInterop = Microsoft.Office.Interop.Excel;
...
public class WorkbookWrapper : IDisposable
{
protected internal ExcelInterop.Workbook _wb;
public WorkbookWrapper(ExcelInterop.Workbook workbook)
{
_wb = workbook;
}
public WorkbookWrapper(WorkbookWrapper workbookWrapper)
{
_wb = workbookWrapper._wb;
}
#region IDisposable
// basic Dispose function which releases _wb COM Object (omitted to shorten post length)
#endregion
...
}
For one particular project I'm working on, I've found it necessary to attach some additional information to WorkbookWrapper objects, so I've extended it:
class LinkingWorkbookWrapper : WorkbookWrapper
{
internal string workbookGUID = null;
internal LinkingWorkbookWrapper(WorkbookWrapper workbookWrapper, string GUID) : base(workbook)
{
workbookGUID = GUID;
}
...
}
This particular class uses the WorkbookWrapper(WorkbookWrapper) constructor to store a new reference to the Interop Workbook, this is suddenly problematic when using functions like the following:
public static void ProcessAllCharts(WorkbookWrapper wbw)
{
LinkingWorkbookWrapper lwbw = null;
if(wbw is LinkingWorkbookWrapper)
lwbw = (LinkingWorkbookWrapper)wbw;
else
lwbw = new LinkingWorkbookWrapper(wbw, GenerateGUID());
//... do stuff ...
}
For now let's say that the function must accept normal WorkbookWrappers. When is the appropriate time to dispose of lwbw? If I do so at the end of ProcessAllCharts I may separate the COM Object referenced in the original wbw from its RCW; on the other hand, if I do not dispose of lwbw, I run the risk of leaving a reference to the COM Object floating in the ether.
This one really belongs to Hans Passant who casually dropped by the comments of the original question but never posted an actual answer.
In a lengthy answer to another question, he details why manually releasing is a fool's errand at best. He also goes into a fair bit of detail as to why we actually get these ghost instances hanging around, and how to rid ourselves of them. I really encourage anyone having this problem to go read the entire post (it's very informative) but if you're in a pinch and need to now, let me summarize it:
Yup, that's it. That's all there is to it. The debugger is a bit of a nag and seems to like convincing the garbage collector that some things are still important when they're really not. I know, you don't think this is your problem, you think this is craziness. I felt the same way, but give it a try; fixed my problem in a jiffy.
Thanks again, Hans Passant, you stoic C-Sharpian you.
Related
I'm working on my little game project as a way to learn and practice C# and I've encountered a design problem. Let's suppose we have following set of classes:
interface IGameState
{
//Updates the state and returns next active state
//(Probably itself or a new one)
IGameState Tick();
}
class Game
{
public Game(IGameState initialState)
{
activeState = initialState;
}
public void Tick()
{
activeState = activeState.Tick();
}
IGameState activeState;
}
Game is basically a state machine for GameStates. We could have MainMenuState,LoadingState or SinglePlayingState. But adding MultiplayerState (which would represent playing a multiplayer game) requires a socket to connect to the server:
class MultiplayerState : IGameState, IDisposable
{
public IGameState Tick()
{
//Game logic...
//Communicate with the server using the Socket
//Game logic...
//Render the game
return this;//Or something else if the player quits
}
public void Dispose()
{
server.Dispose();
}
//Long-living, cannot be in method-scope
Socket server;//Or similar network resource
}
Well and here's my problem, I cannot pass it to Game because it doesn't know it should dispose of it and the calling code cannot easily know when the game doesn't need it anymore. This class design is almost exactly what I have implemented so far and I would be fine with adding IDisposable to IGameState but I don't think its a good design choice, after all not all IGameStates have resources. Furthermore this state machine is meant to be dynamic in a sense that any active IGameState can return new state. So Game really doesn't have know which are disposable and which are so it would have to just test-cast everything.
So this got me asking few questions:
If I have a class that claims the ownership over an argument of non-sealed type (e.g. initialState in Game's ctor) should I always assume it can be IDisposable? (Probably not)
If I have an IDisposable instance should I ever give up its ownership by casting to a base not implementing IDisposable? (Probably no)
I gather from this that IDisposable feels like a quite unique interface with significant lossy(*) semantics - it cares about its own lifetime. That seems in direct conflict with idea of GC itself that offers guaranteed but non-deterministic memory management. I come from C++ background so it really feels like it tries to implement RAII concept but manually with Dispose(destructor) being called as soon as there are 0 references to it. I don't mean this as a rant on C# at all more like am I missing some language feature? Or perhaps C#-specific pattern for this? I know there's using but that's method-scope only. Next there are finalizers which can ensure a call to Dispose but are still nondeterministic, is there anything else? Perhaps automatic reference counting like C++' shared_ptr?
As I've said the above example can be solved (but I don't think it should) by different design but doesn't answer cases where that might not be possible, so please don't focus on it too much. Ideally I would like to see general patterns for solving similar problems.
(*) Sorry, perhaps not a good word. But I mean that a lot of interfaces express a behaviour and that if class implements said interface it just says "Hey, I can also do these things but if you ignore that part of me I still work just fine". Forgetting IDisposable is not lossless.
I've found following question which shows that IDisposable spreads by composition or alternatively it could spread through inheritance. That seems correct to me, requires more typing, but OK. Also that's exactly how MultiplayerState got infected. But in my example with Game class it also wants to spread upstream and that doesn't feel right.
Last questions might be if there should even be any lossy interfaces, like if it's the right tool for the job and in that case what is? Or are there other commonly used lossy interfaces that I know should about?
All of your questions are valid discussions; however, when it comes to IDisposable you are in an unknown condition if you pass it to a type, not knowing if that type will dispose of it properly. For this reason, as a rule, the original owner / initializer of the disposable type should always be in charge of disposing.
So in your case, whoever instantiates MultiplayerState is responsible for disposing of it also. If you have to instantiate it, then pass it to the GameState and dispose of it later then the original owner of MultiplayerState should be required to track that somehow and dispose of it properly.
Also, when implementing IDisposable I highly recommend adding disposing to the destructor of the class as well. This is a fail safe, incase the disposable type isn't disposed of properly or properly implemented.
Example:
public void Dispose()
{
server.Dispose();
GC.SuppressFinalize(this);
}
~MultiplayerState() => Dispose()
I talk about this more here if you're interested.
Thank you for your attention. I'm new to some VS2013 code which is a mixture of C++ plus some microsoft specific extensions. The code has a class like
ref class Foo {
Bar^ bar_; // somewhere else, bar_ = gcnew Bar...
};
Now I'd need to add an unmanaged member, from online search it seems like I can do
ref class Foo {
Bar ^ bar_;
Unmanaged* ptr_; // somewhere else, ptr = new Unmanaged();
~Foo() {
this->!Foo();
}
!Foo() {
delete ptr_;
// do I need anything to deal with bar_?
}
};
The questions are:
1) is this finalizer/destructor the way to go?
2) do I need to write anything extra for bar_ now that I'm explicitly writing the finalizer/destructor?
3) are there cleaner way to do it?
1) is this finalizer/destructor the way to go?
Yes.
2) do I need to write anything extra for bar_
Nothing that is obvious from the snippets. But if the Bar class is disposable as well then you probably ought to add delete bar_; to the destructor. Not to the finalizer. And not if you passed the reference to other code so you can't be sure that this reference is the last one still using the Bar object.
3) are there cleaner way to do it?
No. There are other ways to do it. You could for example consider to not add the destructor. Having one gives the code that uses the class the burden of calling it. Typically that would be C# or VB.NET code, it would have to use the using statement or call Dispose() explicitly. Keep in mind that they often forget. Or don't have a good way to call it.
If such code is not expected to create a lot of instances of Foo and the Unmanaged class merely uses a bit of memory then the finalizer might well be good enough. Or if the Foo object is expected to live for the lifetime of the app, pretty common, then disposing is pointless. Even if it does use a lot of memory then GC::AddMemoryPressure() is a pretty nice alternative. Makes your class easier to use.
And you could consider wrapping the Unmanaged pointer in its own class so Foo doesn't need a finalizer anymore. Along the pattern of the SafeHandle classes in .NET, SafeBuffer is the closest match. That tends to be overkill however in a C++/CLI wrapper, delete failure in particular is nothing you want to hide.
But what you have gets the job done.
This question already has answers here:
Is it abusive to use IDisposable and "using" as a means for getting "scoped behavior" for exception safety?
(12 answers)
Closed 8 years ago.
Background:
Similar to this question, I am looking to use IDisposable for something other than what it was designed for.
The goal:
The application for this isn't terribly relevant, but just for a good example: I have a Windows Forms application where I implement an Undo design pattern. Typically that is done by intercepting "Value Changed" sorts of events from UI elements. For a DataGridView, CellEndEdit and so forth. However there are cases in which I programmatically change data, and I want to do the things each Undo action tracks, without tracking them.
So far:
I have a way to do all that, but I manage my "Should I Undo" logic on a count:
private int _undoOverrides = 0;
public bool ShouldUndo { get { return _undoOverrides < 1; } }
public void DoNotUndo() { ++_undoOverrides; }
public void ResumeUndo() { --_undoOverrides; }
Now, this works well but you have to remember to call ResumeUndo() at the end of such business logic that begins with DoNotUndo(). And I thought:
Maybe I'm not too much of an idiot to screw that up, but what if I had to expose this interface in code I pass down? I would like if the compiler could take care of this for me, if possible.
The idea:
I am considering using a class implementing IDisposable for this. That way, a user of my code could use a using block and never worry about housekeeping chores. This is what I have so far:
private static int _refCount = 0;
public static int ReferenceCount { get { return _refCount; } }
class HallPass : IDisposable
{
protected bool bActive;
public HallPass()
{
++Program._refCount;
bActive = true;
Console.WriteLine("Acquired hallpass!");
}
public void Dispose()
{
if (bActive)
--Program._refCount;
bActive = false;
Console.WriteLine("Hallpass expired!");
}
}
I included a boolean so that I'm sure I don't double-count back down on Dispose(). So all you have to do to use a HallPass is:
using (new HallPass())
{
// do things...
}
The question is:
Is this a good idea? Why might this be a bad idea? Any gotchas I should know about?
Also, and I feel stupid for this, but I'm pretty sure reference count is not the right term for it. It's like a reference count, but there's no reference to manage or memory to free. Edit: It could be, it's just not right now.
It's like a mutex or a critical section in that you're trying to make an exception (another misnomer, because I don't mean the kind you throw) to a rule during a section of code, but it's not either of those because they're meant to be mutually exclusive within a scope--this is designed to be done in a nested fashion if you wish. That's why it's a count, not a boolean.
The first concern of mine is Program._refCount can be accessed from more than one threads and it is not being synchronized. But you can argue that your application is single threaded.
The next and bigger concern is you are not really using the disposable pattern in the way it is supposed to be used. I personally believe that using a pattern in the way it should be used is important, especially when you are not the only person who is working on the code.
Instead of remembering to call ResumeUndo(), now you need to keep in mind that you must call Dispose(). Question is: will it be natural for your team members to realize that they need to call Dispose () when they want to use the HallPass? (using statement is nice, but it cannot be used in every scenario. If there is a HallPass who lives longer than the scope of a single method, you cannot wrap it in a using statement)
Although it is bad to forget call Dispose() on IDisposible, it usually does not affect the correctness of your program - yes, your program will have performance problems, leaks etc., but functionally it usually is still correct. However for your HallPass, if anyone forgets to call Dispose(), I suppose there will be a functional bug. And the bug is hard to trace.
Introduction
I just thought of a new design pattern. I'm wondering if it exists, and if not, why not (or why I shouldn't use it).
I'm creating a game using an OpenGL. In OpenGL, you often want to "bind" things -- i.e., make them the current context for a little while, and then unbind them. For example, you might call glBegin(GL_TRIANGLES) then you draw some triangles, then call glEnd(). I like to indent all the stuff inbetween so it's clear where it starts and ends, but then my IDE likes to unindent them because there are no braces. Then I thought we could do something clever! It basically works like this:
using(GL.Begin(GL_BeginMode.Triangles)) {
// draw stuff
}
GL.Begin returns a special DrawBind object (with an internal constructor) and implements IDisposable so that it automatically calls GL.End() at the end of the block. This way everything stays nicely aligned, and you can't forget to call end().
Is there a name for this pattern?
Usually when I see using used, you use it like this:
using(var x = new Whatever()) {
// do stuff with `x`
}
But in this case, we don't need to call any methods on our 'used' object, so we don't need to assign it to anything and it serves no purpose other than to call the corresponding end function.
Example
For Anthony Pegram, who wanted a real example of code I'm currently working on:
Before refactoring:
public void Render()
{
_vao.Bind();
_ibo.Bind(BufferTarget.ElementArrayBuffer);
GL.DrawElements(BeginMode.Triangles, _indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
BufferObject.Unbind(BufferTarget.ElementArrayBuffer);
VertexArrayObject.Unbind();
}
After refactoring:
public void Render()
{
using(_vao.Bind())
using(_ibo.Bind(BufferTarget.ElementArrayBuffer))
{
GL.DrawElements(BeginMode.Triangles, _indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
}
}
Notice that there's a 2nd benefit that the object returned by _ibo.Bind also remembers which "BufferTarget" I want to unbind. It also draws your atention to GL.DrawElements, which is really the only significant statement in that function (that does something noticeable), and hides away those lengthy unbind statements.
I guess the one downside is that I can't interlace Buffer Targets with this method. I'm not sure when I would ever want to, but I would have to keep a reference to bind object and call Dispose manually, or call the end function manually.
Naming
If no one objects, I'm dubbing this Disposable Context Object (DCO) Idiom.
Problems
JasonTrue raised a good point, that in this scenario (OpenGL buffers) nested using statements would not work as expected, as only one buffer can be bound at a time. We can remedy this, however, by expanding on "bind object" to use stacks:
public class BufferContext : IDisposable
{
private readonly BufferTarget _target;
private static readonly Dictionary<BufferTarget, Stack<int>> _handles;
static BufferContext()
{
_handles = new Dictionary<BufferTarget, Stack<int>>();
}
internal BufferContext(BufferTarget target, int handle)
{
_target = target;
if (!_handles.ContainsKey(target)) _handles[target] = new Stack<int>();
_handles[target].Push(handle);
GL.BindBuffer(target, handle);
}
public void Dispose()
{
_handles[_target].Pop();
int handle = _handles[_target].Count > 0 ? _handles[_target].Peek() : 0;
GL.BindBuffer(_target, handle);
}
}
Edit: Just noticed a problem with this. Before if you didn't Dispose() of your context object there wasn't really any consequence. The context just wouldn't switch back to whatever it was. Now if you forget to Dispose of it inside some kind of loop, you're wind up with a stackoverflow. Perhaps I should limit the stack size...
A similar tactic is used with Asp.Net MVC with the HtmlHelper. See http://msdn.microsoft.com/en-us/library/system.web.mvc.html.formextensions.beginform.aspx (using (Html.BeginForm()) {....})
So there's at least one precedent for using this pattern for something other than the obvious "need" for IDisposable for unmanaged resources like file handles, database or network connections, fonts, and so on. I don't think there's a special name for it, but in practice, it seems to be the C# idiom that serves as the counterpart to the C++ idiom, Resource Acquisition is Initialization.
When you're opening a file, you're acquiring, and guaranteeing the disposal of, a file context; in your example, the resource you're acquiring is a is a "binding context", in your words. While I've heard "Dispose pattern" or "Using pattern" used to describe the broad category, essentially "deterministic cleanup" is what you're talking about; you're controlling the lifetime the object.
I don't think it's really a "new" pattern, and the only reason it stands out in your use case is that apparently the OpenGL implementation you're depending on didn't make a special effort to match C# idioms, which requires you to build your own proxy object.
The only thing I'd worry about is if there are any non-obvious side effects, if, for example, you had a nested context where there were similar using constructs deeper in your block (or call stack).
ASP.NET/MVC uses this (optional) pattern to render the beginning and ending of a <form> element like this:
#using (Html.BeginForm()) {
<div>...</div>
}
This is similar to your example in that you are not consuming the value of your IDisposable other than for its disposable semantics. I've never heard of a name for this, but I've used this sort of thing before in other similar scenarios, and never considered it as anything other than understanding how to generally leverage the using block with IDisposable similar to how we can tap into the foreach semanatics by implementing IEnumerable.
I would this is more an idiom than a pattern. Patterns usually are more complex involving several moving parts, and idioms are just clever ways to do things in code.
In C++ it is used quite a lot. Whenever you want to aquire something or enter a scope you create an automatic variable (i.e. on the stack) of a class that begins or creates or whatever you need to be done on entry. When you leave the scope where the automatic variable is declared the destructor is called. The destructor should then end or delete or whatever is required to clean up.
class Lock {
private:
CriticalSection* criticalSection;
public:
Lock() {
criticalSection = new CriticalSection();
criticalSection.Enter();
}
~Lock() {
criticalSection.Leave();
delete criticalSection;
}
}
void F() {
Lock lock();
// Everything in here is executed in a critical section and it is exception safe.
}
I had trouble coming up with a good way to word this question, so let me try to explain by example:
Suppose I have some interface. For simplicity's sake, I'll say the interface is IRunnable, and it provides a single method, Run. (This is not real; it's only an example.)
Now, suppose I have some pre-existing class, let's call it Cheetah, that I can't change. It existed before IRunnable; I can't make it implement my interface. But I want to use it as if it implements IRunnable--presumably because it has a Run method, or something like it. In other words, I want to be able to have code that expects an IRunnable and will work with a Cheetah.
OK, so I could always write a CheetahWrapper sort of deal. But humor me and let me write something a little more flexible--how about a RunnableAdapter?
I envision the class definition as something like this:
public class RunnableAdapter : IRunnable {
public delegate void RunMethod();
private RunMethod Runner { get; set; }
public RunnableAdapter(RunMethod runner) {
this.Runner = runner;
}
public void Run() {
Runner.Invoke();
}
}
Straightforward enough, right? So with this, I should be able to make a call like this:
Cheetah c = new Cheetah();
RunnableAdapter ra = new RunnableAdapter(c.Run);
And now, voila: I have an object that implements IRunner and is, in its heart of hearts, a Cheetah.
My question is: if this Cheetah of mine falls out of scope at some point, and gets to the point where it would normally be garbage collected... will it? Or does this RunnableAdapter object's Runner property constitute a reference to the original Cheetah, so that it won't be collected? I certainly want that reference to stay valid, so basically I'm wondering if the above class definition is enough or if it would be necessary to maintain a reference to the underlying object (like via some private UnderlyingObject property), just to prevent garbage collection.
Yes, that reference remains valid, and can in fact be retrieved using the Delegate.Target property -- in your code, as ra.Runner.Target.
As others said it counts as a reference. You might find this story interesting.
http://asserttrue.blogspot.com/2008/11/garbage-collection-causes-car-crash.html
If not, that sounds like a broken garbage collector.
Yes, the delegate counts as a reference. Your object will not be garbage collected until the delegate is also unreachable.