Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3273324
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T18:55:12+00:00 2026-05-17T18:55:12+00:00

Is there any nice pattern in .Net for ensuring that IDisposable fields owned by

  • 0

Is there any nice pattern in .Net for ensuring that IDisposable fields owned by an object will get disposed if an exception is thrown during construction, possibly during a field initializer? The only way to surround field initializers in a Try/Catch block is if the block is outside the call to the constructor, which will make it rather difficult for cleanup code to properly dispose of anything.

The only approach I can figure would be to the object inherit from a base class whose constructor takes something like an array of IDisposable, and sets the first item in that array to point to itself. All constructors the descendant classes should be Private or Protected, and include that parameter. Instantiation should be via factory methods, which will declare an array of one IDisposable and pass it to the appropriate constructor. If the constructor fails, the factory method will have a reference to the partially-constructed object, which it can then dispose (the dispose method must, of course, be prepared to accept the possibility that the object may not be fully constructed).

The approach could be extended by having the object keep a list of iDisposable objects it creates, to allow the objects to be cleaned up without having to explicitly dispose each one; such a list would be useful in conjunction with the factory-method-calls-dispose approach, but is largely orthogonal to it.

Any thoughts?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T18:55:12+00:00Added an answer on May 17, 2026 at 6:55 pm

    I’ve come up with a pattern that seems pretty good. It’s inspired by an someone posted on CodeProject.com–using a list to keep track of disposables; raiiBase(of T) is a base class suitable for any class whose constructor takes a single parameter. The class constructor must be protected, and construction must be done via factory method. The static makeRaii() constructor takes a delegate to a factory function, which must accept a Stack(of iDisposable) along with a parameter of the class’s expected type. A sample usage:

    Public Class RaiiTest
        Inherits raiiBase(Of String)
        Dim thing1 As testDisposable = RAII(New testDisposable("Moe " & creationParam, "a"))
        Dim thing2 As testDisposable = RAII(New testDisposable("Larry " & creationParam, "b"))
        Dim thing3 As testDisposable = RAII(New testDisposable("Shemp " & creationParam, "c"))
        Dim thing4 As testDisposable = RAII(New testDisposable("Curly " & creationParam, "d"))
    
        Protected Sub New(ByVal dispList As Stack(Of IDisposable), ByVal newName As String)
            MyBase.New(dispList, newName)
        End Sub
    
        Private Shared Function _newRaiiTest(ByVal dispList As Stack(Of IDisposable), ByVal theName As String) As RaiiTest
            Return New RaiiTest(dispList, theName)
        End Function
    
        Public Shared Function newRaiiTest(ByVal theName As String) As RaiiTest
            Return makeRaii(Of RaiiTest)(AddressOf _newRaiiTest, theName)
        End Function
    
        Shared Sub test(ByVal st As String)
            Try
                Using it As RaiiTest = newRaiiTest(st)
                    Debug.Print("Now using object")
                End Using
                Debug.Print("No exceptions thrown")
            Catch ex As raiiException
                Debug.Print("Output exception: " & ex.Message)
                If ex.InnerException IsNot Nothing Then Debug.Print("Inner exception: " & ex.InnerException.Message)
                For Each exx As Exception In ex.DisposalExceptions
                    Debug.Print("Disposal exception: " & exx.Message)
                Next
            Catch ex As Exception
                Debug.Print("Misc. exception: " & ex.Message)
            End Try
        End Sub
    End Class
    

    Since raiiTest inherits raiiBase(of String), to create a class instance, call newRaiiTest with a string parameter. RAII() is a generic function that will register its argument as an iDisposable that will need cleaning up, and then return it. All registered disposables will be Disposed when either Dispose is called on the main object, or when an exception is thrown in the construction of the main object.

    Here’s the riaaBase class:

    Option Strict On
    Class raiiException
        Inherits Exception
        ReadOnly _DisposalExceptions() As Exception
        Sub New(ByVal message As String, ByVal InnerException As Exception, ByVal allInnerExceptions As Exception())
            MyBase.New(message, InnerException)
            _DisposalExceptions = allInnerExceptions
        End Sub
        Public Overridable ReadOnly Property DisposalExceptions() As Exception()
            Get
                Return _DisposalExceptions
            End Get
        End Property
    End Class
    
    Public Class raiiBase(Of T)
        Implements IDisposable
    
        Protected raiiList As Stack(Of IDisposable)
        Protected creationParam As T
        Delegate Function raiiFactory(Of TT As raiiBase(Of T))(ByVal theList As Stack(Of IDisposable), ByVal theParam As T) As TT
    
        Shared Function CopyFirstParamToSecondAndReturnFalse(Of TT)(ByVal P1 As TT, ByRef P2 As TT) As Boolean
            P2 = P1
            Return False
        End Function
    
        Shared Function makeRaii(Of TT As raiiBase(Of T))(ByVal theFactory As raiiFactory(Of TT), ByVal theParam As T) As TT
            Dim dispList As New Stack(Of IDisposable)
            Dim constructionFailureException As Exception = Nothing
            Try
                Return theFactory(dispList, theParam)
            Catch ex As Exception When CopyFirstParamToSecondAndReturnFalse(ex, constructionFailureException)
                ' The above statement let us find out what exception occurred without having to catch and rethrow
                Throw ' Should never happen, since we should have returned false above
            Finally
                If constructionFailureException IsNot Nothing Then
                    zapList(dispList, constructionFailureException)
                End If
            End Try
        End Function
    
        Protected Sub New(ByVal DispList As Stack(Of IDisposable), ByVal Params As T)
            Me.raiiList = DispList
            Me.creationParam = Params
        End Sub
    
        Public Shared Sub zapList(ByVal dispList As IEnumerable(Of IDisposable), ByVal triggerEx As Exception)
            Using theEnum As IEnumerator(Of IDisposable) = dispList.GetEnumerator
                Try
                    While theEnum.MoveNext
                        theEnum.Current.Dispose()
                    End While
                Catch ex As Exception
                    Dim exList As New List(Of Exception)
                    exList.Add(ex)
                    While theEnum.MoveNext
                        Try
                            theEnum.Current.Dispose()
                        Catch ex2 As Exception
                            exList.Add(ex2)
                        End Try
                    End While
                    Throw New raiiException("RAII failure", triggerEx, exList.ToArray)
                End Try
            End Using
        End Sub
    
        Function RAII(Of U As IDisposable)(ByVal Thing As U) As U
            raiiList.Push(Thing)
            Return Thing
        End Function
    
        Shared Sub zap(ByVal Thing As IDisposable)
            If Thing IsNot Nothing Then Thing.Dispose()
        End Sub
    
        Private raiiBaseDisposeFlag As Integer = 0 ' To detect redundant calls
    
        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If disposing AndAlso Threading.Interlocked.Exchange(raiiBaseDisposeFlag, 1) = 0 Then
                zapList(raiiList, Nothing)
            End If
        End Sub
    
    #Region " IDisposable Support "
        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
    #End Region
    
    End Class
    

    Note that a custom exception type will be thrown if disposal fails for any or all of the registered disposable objects. InnerException will indicate whether the constructor failed; to see which disposer(s) failed, check DisposalExceptions.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Is there any free or commercial component written in .NET (no COM interop) that
Hi are there any nice videos on how to use exceptions in Delphi.
Hi are there any nice videos or other resources on how to use Interfaces
i'm wondering if there is any nice and neat tool to replace the GNU
Is there any good alternative to ASpell? It's nice open source, but haven't been
These ribbon in stackoverflow and uservoice.com looks nice. is there any javascript library/jquery plugin
Is there any way to capture the MouseDown even from the .NET 2.0 TextBox
is there any nice GNU way how to measure average (worst case, best case)
Is there any way to check whether a file is locked without using a
Is there any query which can return me the number of revisions made to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.