Do we have Unmanaged resources in C#?

Vinod Menezes picture Vinod Menezes · Jun 17, 2011 · Viewed 7.8k times · Source

I had a discussion with my friend about managed and unmanaged resources in c#.

According to my friend:

1.a) Every object in C# is managed and there is nothing like unmanaged object or resource when we code in C#. Unmanaged resource concept comes only with C++.

1.b) Whether we have managed or unmanaged resource in C++ we need to free it explicitly. Since we have automatic garbage collector in C# we need need not think about managing resources.

According to me:

2.a)If we do not have unmanaged resource then why do we need a finalizer or Dispose method in C#?

2.b)Garbage collector only has information about allocated memory and not about the state of the resources. Therefore we need to use dispose method to release resources in C#.

I need help in understanding which of the above arguments are correct and information about unmanaged resource in c#, whether they exist or not?

Thanks in Advance.

Answer

Hans Passant picture Hans Passant · Jun 17, 2011

No, it is impossible to write a C# program without using unmanaged resources. It is inevitable, a C# program runs on an operating system that is 100% unmanaged. If you use a file then you use an operating system resource. A network connection. A thread. The console. Etcetera, all very much unmanaged resources.

That fact is however hidden pretty well in .NET. The framework library has nice wrapper classes for these native objects. FileStream, Socket, Thread, Console, etcetera. Memory is an operating system resource too, the garbage collector is a wrapper around it.

Of all of these resources, only the memory resource is truly automatically managed. The rest of them get some measure of help by virtue of their wrapper class. Their finalizer is the key, it releases the operating system resource when it is called. That's pretty close to automatic, the garbage collector notices that the wrapper class object is no longer referenced anywhere so it releases it, the finalizer then ensures that the unmanaged resource is released as well.

That usually works well, you can often ignore these implementation details in your code. Many programmers do.

There is a problem with finalizers though, they take a while to start running. It takes a garbage collection to get them started, that can take anywhere from a handful of milliseconds to minutes. It is unpredictable, it depends on the rate in which you consume memory in your code. If you don't use a lot of it then it will take a long time.

You cannot always afford to wait that long for an unmanaged resource to get released. A file is a good example. When you open one to read data from the file then you really should close the file when you're done reading. If you wait until the finalizer gets that job done then you run the risk of your program failing when it needs to open the file again, some time later. You might have locked yourself out by opening the file with FileShare.None, it locks your own code out as well. No big deal: you call Close() to close the file when you're done reading. To be sure it gets closed, you should put the Close() call in a finally block so it runs even if the code aborts due to an exception. In effect, you run the finalizer code explicitly.

A more serious case is an operating system resource that is very expensive. Good examples of those are bitmaps, they can take a lot of unmanaged memory, or database connections, there is a pool for them that by default only contains 100 of them. For these, you can get yourself well into a situation where letting the finalizer take care of releasing the resource just doesn't work because it takes too long. Your program dies on an exception before the finalizer can run. Usually pretty hard to diagnose because that tends to only happens when your program is under load. Always hard to debug problems that occur when lots of things are going on, on a machine that is not on your desktop.

The .NET designers recognized this need and designed the IDisposable interface. Its Dispose() method was designed to run the code that normally is run by the finalizer, giving you a way to explicitly releasing a resource rather than waiting for the garbage collector to get around to it. And the language designers jumped on that bandwagon by adding the using keyword to their language, ensuring that IDisposable.Dispose() is automatically called.

Using using or Dispose() in your code for any object that implements IDisposable is optional, as explained above, but considered vital by many .NET programmers. Mostly because everybody started .NET programming without it and ran into a problem sooner or later when their programs got big. It is even prescribed on classes where calling Dispose() makes no sense, like MemoryStream. And causes mental anguish when a class should implement IDisposable but doesn't, like Thread. Or when a class implements both Dispose and Close (it makes no difference). For comparison, Java has the same considerations but doesn't have IDisposable.