资源管理:使用关键字

本主题介绍关键字和函数,该关键字 useusing 函数可以控制资源的初始化和释放。

资源

术语 资源 以多种方式使用。 是的,资源可以是应用程序使用的数据,例如字符串、图形等,但在此上下文中, 资源 是指软件或作系统资源,例如图形设备上下文、文件句柄、网络和数据库连接、并发对象(如等待句柄等)。 应用程序使用这些资源涉及从作系统或其他资源提供程序获取资源,然后随后将资源发布到池,以便将其提供给另一个应用程序。 当应用程序不将资源释放回公共池时,会出现问题。

管理资源

若要高效和负责任的管理应用程序中的资源,必须以可预测的方式及时发布资源。 .NET Framework 通过提供 System.IDisposable 接口来帮助执行此作。 实现 System.IDisposable 的类型具有 System.IDisposable.Dispose 方法,该方法可正确释放资源。 编写良好的应用程序保证 System.IDisposable.Dispose ,当不再需要保留有限资源的任何对象时,会立即调用。 幸运的是,大多数 .NET 语言都提供支持,使这更容易,F# 也不例外。 有两个有用的语言构造支持释放模式: use 绑定和 using 函数。

使用绑定

关键字 use 具有类似于绑定的 let 窗体:

use value = expression

它提供与绑定相同的功能 let ,但在值超出范围时对 Dispose 值添加调用。 请注意,编译器在值上插入 null 检查,以便如果值为 null,则不会尝试调用 Dispose 它。

以下示例演示如何使用 use 关键字自动关闭文件。

open System.IO

let writetofile filename obj =
   use file1 = File.CreateText(filename)
   file1.WriteLine("{0}", obj.ToString() )
   // file1.Dispose() is called implicitly here.

writetofile "abc.txt" "Humpty Dumpty sat on a wall."

多个实例 use 按声明它们的反向顺序释放。 也就是说,第一 use 个将是最后一个发布的。

注释

可以在计算表达式中使用 use ,在这种情况下使用自定义版本的 use 表达式。 有关详细信息,请参阅 序列异步表达式任务表达式计算表达式

using 函数

using 函数具有以下形式:

using表达式1function-or-lambda

using在表达式中,expression1 创建必须释放的对象。 expression1(必须释放的对象)的结果将成为函数或 lambda 的参数、值,该函数是需要与 expression1 生成的匹配的类型的单个剩余参数的函数,或者需要该类型的参数的 lambda 表达式。 在函数执行结束时,运行时调用 Dispose 并释放资源(除非值为 null,在这种情况下,不会尝试对 Dispose 的调用)。

以下示例演示了具有 lambda 表达式的 using 表达式。

open System.IO

let writetofile2 filename obj =
    using (System.IO.File.CreateText(filename)) ( fun file1 ->
        file1.WriteLine("{0}", obj.ToString() )
    )

writetofile2 "abc2.txt" "The quick sly fox jumps over the lazy brown dog."

下一个示例显示具有函数的 using 表达式。

let printToFile (file1 : System.IO.StreamWriter) =
    file1.WriteLine("Test output");

using (System.IO.File.CreateText("test.txt")) printToFile

请注意,该函数可以是已应用某些参数的函数。 下面的代码示例演示了这一点。 它创建一个包含字符串 XYZ的文件。

let printToFile2 obj (file1 : System.IO.StreamWriter) =
    file1.WriteLine(obj.ToString())

using (System.IO.File.CreateText("test.txt")) (printToFile2 "XYZ")

函数 usinguse 绑定几乎等效于完成相同作的方法。 该 using 关键字提供对何时调用的 Dispose 更多控制。 使用 using时, Dispose 在函数或 lambda 表达式的末尾调用;使用 use 关键字时, Dispose 在包含代码块的末尾调用。 一般情况下,应首选使用 use 而不是 using 函数。

另请参阅