|
-
Mar 22nd, 2023, 09:32 AM
#1
Thread Starter
Lively Member
[RESOLVED] Disposing Multiple Instantiated Objects (Classes) With Long Run-times
At run-time, my Winform app starts (instantiates) multiple classes which are all IDisposable. Each class spawns a threaded method which often has long run times (several minutes).
If a run only requires use of one class, then naturally I won't thread the method in that class and therefore can dispose the class immediately thereafter. The choice of threading the method or not is set by use of a boolean, for example, called threadAllMethods.
Code:
threadAllMethods = false
Dim MyMath1 as New MathClass1(param1, param2, param3)
MyMath1.Dispose()
If a run requires use of all classes, then I will thread the method in each class, so that use of multiple threads can run simultaneously.
Code:
threadAllMethods = true
Dim MyMath1 as New MathClass1(param1, param2, param3)
Dim MyMath2 as New MathClass2(param1, param2, param3)
Dim MyMath3 as New MathClass3(param1, param2, param3)
Dim MyMath4 as New MathClass4(param1, param2, param3)
Dim MyMath5 as New MathClass5(param1, param2, param3)
However, when all classes are instantiated and their methods are threaded, you cannot invoke Dispose immediately thereafter since you need to wait until the threads are completed. Therefore, I define a public list of Object type as follows:
Code:
Public ListOfClasses As New List(Of Object)
Next, after each class is instantiated with method threading, I add the object to the public list of objects:
Code:
threadAllMethods = true
Dim MyMath1 as New MathClass1(param1, param2, param3)
ListOfClasses.Add(MyMath1)
Dim MyMath2 as New MathClass2(param1, param2, param3)
ListOfClasses.Add(MyMath2)
Dim MyMath3 as New MathClass3(param1, param2, param3)
ListOfClasses.Add(MyMath3)
Dim MyMath4 as New MathClass4(param1, param2, param3)
ListOfClasses.Add(MyMath4)
Dim MyMath5 as New MathClass5(param1, param2, param3)
ListOfClasses.Add(MyMath5)
Then, by using AutoResetEvents with e.g. MyMath1ThreadDone.Set specified at the end of a threaded method, I wait for all threads (methods) to complete, and then dispose the IDisposable classes using the a Do While:
Code:
MyMath1ThreadDone.WaitOne()
MyMath2ThreadDone.WaitOne()
MyMath3ThreadDone.WaitOne()
MyMath4ThreadDone.WaitOne()
MyMath5ThreadDone.WaitOne()
While (ListOfClasses.Count() > 0)
Dim item As Object = ListOfClasses(0)
ListOfClasses.RemoveAt(0)
item.Dispose
End While
FYI, the Dispose code I am using was fetched from MSDN a while ago, and I am not sure that it guarantees proper finalization:
Code:
#Region "IDisposable"
'---Code entirely copied from MSDN
Private managedResource As System.ComponentModel.Component
Private unmanagedResource As IntPtr
Protected disposed As Boolean = False
Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposed Then
If disposing Then
Try
' managedResource.Dispose()
Catch
End Try
End If
' Add code here to release the unmanaged resource.
unmanagedResource = IntPtr.Zero
' Note that this is not thread safe.
End If
Me.disposed = True
End Sub
'Do not change or add Overridable to these methods.
'Put cleanup code in Dispose(ByVal disposing As Boolean).
Public Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overrides Sub Finalize()
Dispose(False)
MyBase.Finalize()
End Sub
#End Region
Some questions I have are (a) When the methods inside all classes are to be threaded, is it appropriate to load the classes as objects into a list and then wait for all threads to stop and then dispose the classes, and (b) based on the MSDN dispose code I am using, will it finalize correctly, and will it release unmanaged resources as well? (As far as manually disposing GDIObjects, I just spent a lot of time making sure all the Pen, Brush, and bitmaps are individually disposed within their respective methods -- since GDIObjects tend to fill up Byte[] arrays that are unmanaged without handles and are not disposed via IDisposable).
Last, instead of loading all the classes into an object list, and then waiting for all their threaded methods to complete and then disposing classes en-block, can I use the following code at the end of a threaded method to invoke disposal of its parent class, as follows?
Code:
Sub DoTheMath(ByVal param1 As Double, ByVal param2 As Double, ByVal param3 As Double)
'....do some work
MyMath1ThreadDone.Set() 'always used/needed for thread mgmt
Me.Dispose
End Sub
Last edited by pel11; Mar 30th, 2023 at 11:29 AM.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|