8 people like it.

Finalizable function object

The snippet shows how to create an F# function value that will call a custom finalizer function when garbage collected. This is done by creating a type that inherits from FSharpFunc.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
/// A type that inherits from FSharpFunc type (F# functions)
/// and overrides the Finalize method with custom handler
type FinalizableFunc<'T, 'R>(f, finalizer) = 
  inherit Microsoft.FSharp.Core.FSharpFunc<'T, 'R>()
  override x.Invoke(a) = f a
  override x.Finalize() = finalizer()

/// Create a function with custom finalizer
let finalizable (f:'T -> 'R) handler =
  // F# does not allow direct cast, so we need to box
  let ff = FinalizableFunc<'T, 'R>(f, handler)
  box ff :?> ('T -> 'R)

/// Create finalizable function & call it
let foo () =
  let f = 
    finalizable 
      (fun n -> n + 1) 
      (fun () -> printfn "bye!")
  f 1

/// The function will be collected on GC.Collect call
foo ()
System.GC.Collect()
Multiple items
type FinalizableFunc<'T,'R> =
  inherit FSharpFunc<'T,'R>
  new : f:('T -> 'R) * finalizer:(unit -> unit) -> FinalizableFunc<'T,'R>
  override Finalize : unit -> unit
  override Invoke : a:'T -> 'R

Full name: Script.FinalizableFunc<_,_>


 A type that inherits from FSharpFunc type (F# functions)
 and overrides the Finalize method with custom handler


--------------------
new : f:('T -> 'R) * finalizer:(unit -> unit) -> FinalizableFunc<'T,'R>
val f : ('T -> 'R)
val finalizer : (unit -> unit)
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Core
new : unit -> FSharpFunc<'T,'U>
val x : FinalizableFunc<'T,'R>
override FinalizableFunc.Invoke : a:'T -> 'R

Full name: Script.FinalizableFunc`2.Invoke
val a : 'T
override FinalizableFunc.Finalize : unit -> unit

Full name: Script.FinalizableFunc`2.Finalize
val finalizable : f:('T -> 'R) -> handler:(unit -> unit) -> ('T -> 'R)

Full name: Script.finalizable


 Create a function with custom finalizer
val handler : (unit -> unit)
val ff : FinalizableFunc<'T,'R>
val box : value:'T -> obj

Full name: Microsoft.FSharp.Core.Operators.box
val foo : unit -> int

Full name: Script.foo


 Create finalizable function & call it
val f : (int -> int)
val n : int
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
namespace System
type GC =
  static member AddMemoryPressure : bytesAllocated:int64 -> unit
  static member CancelFullGCNotification : unit -> unit
  static member Collect : unit -> unit + 2 overloads
  static member CollectionCount : generation:int -> int
  static member GetGeneration : obj:obj -> int + 1 overload
  static member GetTotalMemory : forceFullCollection:bool -> int64
  static member KeepAlive : obj:obj -> unit
  static member MaxGeneration : int
  static member ReRegisterForFinalize : obj:obj -> unit
  static member RegisterForFullGCNotification : maxGenerationThreshold:int * largeObjectHeapThreshold:int -> unit
  ...

Full name: System.GC
System.GC.Collect() : unit
System.GC.Collect(generation: int) : unit
System.GC.Collect(generation: int, mode: System.GCCollectionMode) : unit
Raw view Test code New version

More information

Link:http://fssnip.net/hM
Posted:11 years ago
Author:Tomas Petricek
Tags: function , gc , finalizer