Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I know if a class is a wrapper for an unmanaged resource

Tags:

c#

How do I know if a class in C# is unmanaged, so that if I use it in a self defined class I know whether I have to implement the IDisposable interface?

If I get this article on the MSDN network right, I always have to implement the IDisposible interface when I use an unmanaged resource.

So I've created a little example that you can find below:

class TestClass
{
    private StreamReader reader;

    public UsingTestClass()
    {
        reader = File.OpenText("C:\\temp\\test.txt");

        string s;
        while (!string.IsNullOrEmpty(s = reader.ReadLine()))
        {
            Console.WriteLine(s);
        }

    }
}

The following MSDN article says for example that File is an unamanged ressource, which is also used in my test class. So how can I see, that this class is unamanged? The compiler and ReSharper didn't complain anything.

Thanks in advance.

like image 273
Fabian Avatar asked Mar 09 '16 20:03

Fabian


People also ask

Which of this is the example of unmanaged resources?

However, when you create objects that include unmanaged resources, you must explicitly release those resources when you finish using them. The most common types of unmanaged resources are objects that wrap operating system resources, such as files, windows, network connections, or database connections.

How do you handle unmanaged resources in C#?

The following are two mechanisms to automate the freeing of unmanaged resources: Declaring a destructor (or Finalizer) as a member of your class. Implementing the System. IDisposable interface in your class.

Can garbage collector claim unmanaged objects?

So, the garbage collector is nothing but a background thread that runs continuously. Checks for unused managed objects clean those objects and reclaims the memory. Now, it is important to note that the garbage collector cleans and reclaims unused managed objects only. It does not clean unmanaged objects.

What is unmanaged resources in C sharp?

UnManaged objects are created outside the control of . NET libraries and are not managed by CLR, example of such unmanaged code is COM objects, file streams, connection objects, Interop objects. (Basically, third party libraries that are referred in .


1 Answers

How do I know if a class in C# is unmanaged

That gets you off on the wrong track right away, all classes in C# are managed. The language has no support for using unmanaged classes at all. None of the .NET languages do, except one: C++/CLI. Which is a rather untypical language specifically designed to help a programmer use a native C++ class. Usage of that language is specialized and not relevant to this question.

What matters is whether the managed class is a wrapper for an unmanaged resource. A wrapper is the kind of class that has a purely managed interface but that internally uses an unmanaged resource, usually through pinvoke with the [DllImport] attribute. The resource is almost always represented with an IntPtr. An unmanaged handle or pointer.

Such a wrapper needs a finalizer to ensure that the unmanaged resource is always released. If that doesn't happen then you have a leak, the kind of bug that (eventually) crashes a program when the operating system gets upset about a program using too many resources.

And since it has a finalizer, it also implements IDisposable. Allowing a program to release the unmanaged resource early, before the GC gets around to calling the finalizer. Using the Dispose() method or the using statement is optional, the finalizer is good enough to ensure the job gets done.

But sometimes the finalizer isn't good enough because a program doesn't generate garbage quickly enough and then it is pretty important that you help. You can't really know whether you have to help so most .NET programmers always do. And a subset never does and have not ever noticed a problem in years of programming. We do eventually hear from them at SO :)


Your example of a StreamReader is a good one to get to the next step. StreamReader does not actually wrap an unmanaged resource. All of its code is written in C# and it does not have any pinvoke, there's not an unmanaged bone in its body. And does therefore not have a finalizer. But still has a Dispose() method.

StreamReader got "infected". It is also a wrapper class but for a Stream, not an IntPtr. A purely managed abstract .NET type, itself a wrapper. Which implements IDisposable, now StreamReader has to implement it as well. So when you call the StreamReader's Dispose() method then the Stream.Dispose() method can run.

This is layering at work, there is a hierarchy of classes. StreamReader wraps Stream which wraps FileStream which wraps SafeFileHandle which actually wraps the IntPtr. Only SafeFileHandle has a finalizer.


Understanding the layering is where everybody gives up, that requires pretty deep insight into the way these .NET classes are structured. You can get there but it takes years. There are three basic shortcuts:

  • Have an understanding of how an operating system works. Gives you the insight that a file is an operating system resource, bet your booty that when you use a file there is a need to dispose or close it.

  • Use the MSDN library article for the class you use. When you see it has a Dispose() method then there almost always is a good reason to use it. Sometimes there is not but you'll never be wrong when you use it anyway.

  • Get in trouble, make all the mistakes that every programmer needs to make, use SO or a memory profiler to find out what you did wrong. Nothing ever wrong with learning how to do it right.

like image 112
Hans Passant Avatar answered Sep 28 '22 02:09

Hans Passant