Управление ресурсами: ключевое слово use

В этом разделе описывается ключевое слово use и using функция, которые могут управлять инициализацией и выпуском ресурсов.

Ресурсы

Ресурс термина используется несколькими способами. Да, ресурсы могут быть данными, которые использует приложение, такие как строки, графика и подобные, но в этом контексте ресурсы ссылаются на ресурсы программного обеспечения или операционной системы, такие как контексты графических устройств, дескрипторы файлов, подключения к сети и базам данных, объекты параллелизма, такие как дескриптор ожидания и т. д. Использование этих ресурсов приложениями включает приобретение ресурса из операционной системы или другого поставщика ресурсов, за которым следует более поздний выпуск ресурса в пул, чтобы его можно было предоставить другому приложению. Проблемы возникают, когда приложения не освобождают ресурсы обратно в общий пул.

Управление ресурсами

Чтобы эффективно и ответственно управлять ресурсами в приложении, необходимо быстро и предсказуемо освободить ресурсы. Платформа .NET помогает сделать это, предоставив интерфейс System.IDisposable. Тип, реализующий System.IDisposableSystem.IDisposable.Dispose метод, который правильно освобождает ресурсы. Хорошо написанные приложения гарантируют, что вызывается быстро, System.IDisposable.Dispose когда любой объект, содержащий ограниченный ресурс, больше не нужен. К счастью, большинство .NET языков обеспечивают поддержку для упрощения этого, и F# не является исключением. Существует два полезных языковых конструкции, поддерживающие шаблон удаления: use привязку и using функцию.

использование привязки

Ключевое use слово имеет форму, похожую на привязку let :

использованиевыражения значений =

Он предоставляет те же функции, что 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 (выражение1) function-or-lambda

using В выражении выражение1 создает объект, который должен быть удален. Результат выражения1 (объект, который должен быть удален) становится аргументом, значением для функции или лямбда-функции, которая ожидает один оставшийся аргумент типа, который соответствует значению, созданному выражением expression1, или лямбда-выражение, которое ожидает аргумент этого типа. В конце выполнения функции среда выполнения вызывает Dispose и освобождает ресурсы (если значение не имеет nullзначения, в этом случае вызов dispose не выполняется).

В следующем примере показано 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")

Функция using и привязка use практически эквивалентны тому же способу. Ключевое using слово обеспечивает более контроль над Dispose вызовом. При использовании вызывается в конце функции или лямбда-выражения. При использовании usingDisposeuse ключевого слова Dispose вызывается в конце содержащего блока кода. Как правило, вместо функции следует использовать useusing .

См. также