Should IDisposable be applied cascadingly?

前端 未结 9 1537
灰色年华
灰色年华 2020-12-31 06:48

This is a rather basic question, however I\'m still struggling with it a little.

IDisposable is implemented, when you want to enable the user of an object to free un

相关标签:
9条回答
  • 2020-12-31 07:17

    Yes, you ALWAYS implement IDisposable if you control disposable objects. ALWAYS. Your code won't break if you don't, but it defeats the purpose of having disposable objects if you don't.

    The general rule for GC optimization is:

    • Any class that controls objects not managed by the GC must implement a finalizer (and generally should implement IDisposable as well). This is where the "top level" disposable classes usually come from -- they usually control a HANDLE to a window, socket, mutex, or what have you.
    • Any class that instantiates an IDisposable member should implement IDisposable itself, and properly Dispose() of its constituents.
    • Any function that instantiates an IDisposeable object should properly Dispose() of it when it done being used. Don't let it just drop out of scope.

    These rules may be bent or ignored if you're writing an application for yourself, but when distributing code to others you should be professional and follow the rules.

    The logic here is that when you control memory outside the view of the GC the GC engine can't properly manage your memory usage. On your .NET heap, for example, you may just have a 4-byte pointer, but out in unmanaged land you could have 200 MB of memory being pointed at. The GC engine wouldn't attempt to collect these until you have several dozen, because all it sees is a few bytes; while in the real world it looks a lot like a memory leak.

    Therefore, the rule is, unmanaged memory should get freed immediately when you're done using it (the IDisposable chain does this for you), while managed memory gets freed by the GC engine whenever it gets around to it.

    0 讨论(0)
  • 2020-12-31 07:19

    When you provide explicit control using Dispose, you should provide implicit cleanup using the Finalize method. Finalize provides a backup to prevent resources from permanently leaking if the programmer fails to call Dispose.

    I think best way to implement this is use combination of Dispose and Finalize method. You can find more Here.

    0 讨论(0)
  • 2020-12-31 07:27

    If I understand your question correctly, you have a class that uses a DbConnection. You want to ensure that the DbConnection is correctly disposed when you are done working with it or when your class is disposed. There are a couple of ways to achieve this.

    If you are using a database connection as a local variable in a method then you can leverage the using() {} statement.

    using (SqlConnection sqlConnection = new SqlConnection(connStr))
    {
    ...do stuff with connection here
    }

    The using () {} statement automatically calls Dispose() on objects declared within the (). (It also requires that objects declared in the () implement IDisposable to ensure they can be disposed)

    If you are instead working with a DbConnection as a private variable that is initialized during object construction or some other initialization method then you probably want to implement IDisposable yourself and then call _dbConnection.Dispose() in your Dispose() method. That way, when your object is disposed the db connection object will also dispose.

    public class MyDALObj : IDisposable
    {

    public MyDalObj()
    {
    ... create _dbConn object ...
    }

    public void Dispose()
    {
    _dbConn.Dispose();
    }

    private DbConnection _dbConn;
    }

    0 讨论(0)
提交回复
热议问题