DotNet Objects and Classes Life Time Control

In versions prior to 3ds Max 2010, performing MAXScript garbage collection can delete the DotNet event handlers too early.

With this method available in 3ds Max 2010 and higher, this can be avoided by setting the life time control of the corresponding objects to be handled by DotNet instead of MAXScript.

dotNet.setLifetimeControl {<dotNetObject> | <dotNetClass>} {#mxs | #dotnet}

Controls whether the MAXScript value wrapping the DotNet object or DotNetclass can be garbage collected when there are no MAXScript references to the value ( #mxs ), or whether the DotNet object is destroyed before the MAXScript value can be garbage collected ( #dotnet ).

By default, a dotNetObject value holds a strong reference to the DotNet object, and the DotNet object is deleted only when the dotNetObject value is deleted. This is equivalent to specifying #mxs as second argument in the above method.

If you specify #dotnet as the second argument, the dotNetObject cannot be collected until the DotNet object is deleted. The dotNetObject value holds a weak reference to the DotNet object and the DotNet object is deleted when no other DotNet objects hold a reference to it and a DotNet garbage collection occurs.

EXAMPLE 1 - HANDLERS DELETED

   (
   function whenButtonIsPressed =
   (
   print "Pressed from a .NET button"
   )
   function formIsClosed =
   (
   print "form closed"
   )
   local mButton = dotNetObject "System.windows.forms.button"
   mButton.text = ".NET Button"
   mButton.size = dotNetObject "System.Drawing.Size" 100 100
   mButton.location = dotNetObject "System.Drawing.Point" 50 50
   local hForm = dotNetObject "System.Windows.Forms.Form"
   hForm.controls.add mButton
   dotNet.addEventHandler mButton "click" whenButtonIsPressed
   dotNet.addEventHandler hForm "Closed" formIsClosed
   hForm.show()
   ok
   )
   gc()

Evaluating the above code creates a DotNet Form with a DotNet button and two event handlers - one to print a message to the Listener when the button is pressed and one to print a message when the Form is closed.

Because of the MAXScript Garbage Collection performed after the creation of the Form, both handlers are deleted immediately and nothing is printed when pressing the button or closing the form.

EXAMPLE2 - HANDLERS PRESERVED

By switching the life time control of the button and the form to DotNet, it is ensured that the event handlers of both buttons are preserved after a MAXScript Garbage Collection:

   (
   function whenButtonIsPressed =
   (
   print "Pressed from a .NET button"
   )
   function formIsClosed =
   (
   print "form closed"
   )
   local mButton = dotNetObject "System.windows.forms.button"
   mButton.text = ".NET Button"
   mButton.size = dotNetObject "System.Drawing.Size" 100 100
   mButton.location = dotNetObject "System.Drawing.Point"50 50
   local hForm = dotNetObject "System.Windows.Forms.Form"
   hForm.controls.add mButton
   dotNet.addEventHandler mButton "click" whenButtonIsPressed
   dotNet.addEventHandler hForm "Closed" formIsClosed
   dotNet.setLifetimeControl mButton #dotnet
   dotNet.setLifetimeControl hForm #dotnet
   hForm.show()
   ok
   )
   gc()