这篇文章包含两个相互关联的问题,它们具有共同的清理资源。我已经阅读了SO post以及Microsoft网站上的其他一些文章,试图确定什么是托管资源还是非托管资源。根据我阅读的内容,以下代码块使用.Net托管资源。这来自非DLL F#库。
namespace Toa.csv_lib
open System
open System.Threading
open System.Collections.Generic
open System.Linq
open System.Text
open System.Threading.Tasks
open System.IO
open Microsoft.VisualBasic.FileIO
[<AutoOpen>]
module csv_lib =
let initCsvLib fn delim =
let csvFileH = new TextFieldParser(fn:string)
csvFileH.TextFieldType = FieldType.Delimited |> ignore
csvFileH.SetDelimiters(delim) |> ignore
csvFileH
let readCsvLibLine csvFileH =
(csvFileH:TextFieldParser).ReadFields()
let retCsvData csvFileH =
let csvData = new List<string[]>()
if not (csvFileH:TextFieldParser).EndOfData then
let column_headings = readCsvLibLine csvFileH
csvData.Add(column_headings) |> ignore
let read_rest_of_csv() =
csvData.Add(readCsvLibLine csvFileH) |> ignore
not (csvFileH:TextFieldParser).EndOfData
while read_rest_of_csv() do ignore None
csvData // Last expression is returned.
尽管我相信
csvFileH
和csvData
是托管资源,但我想知道[<AutoOpen>]
是否与之相反,是否需要一个?这将是一条指令,该指令将允许库释放[<AutoOpen>]
中创建的所有资源。我可以重新构造此代码,使
using
周围有csvFileH
,因为仅在读取.csv文件时才需要该句柄。但是,如果返回List<string[]> csvData
类型,则仍将其视为托管资源,该资源将在应用程序关闭时进行垃圾处理。 最佳答案
[<AutoOpen>]
所做的所有工作都是在不使用open
语句的情况下公开模块的内容。而已。它没有运行任何代码,只是自动地公开了一些需要手动公开的东西。
就您而言,当您引用此模块时,实际上并没有执行任何操作。 initCsvLib
是一个纯函数,需要两个args并返回csvFileH
的实例。这里没有正在运行的初始化代码。如果你有例如
module Foo =
let expensiveThing = ExpensiveThing()
let myFn arg1 arg2 =
// This isn't run until the function myFn is called.
let expensiveThing = ExpensiveThing()
// ...
然后,您可能会遇到问题。在那种情况下,尽管您不得不回想起模块实际上是静态类,并且基本上遵循与C#中静态类相同的规则(考虑何时运行静态构造函数),然后再去那里。
但是如果到了这一点,您应该问自己为什么首先要在构造函数中进行如此昂贵的操作...