Поделиться через


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

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

Ресурсы

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

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

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

Привязка use

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

value привязки use = 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.Дополнительные сведения см. в разделах Последовательности (F#), Асинхронные рабочие потоки (F#) и Выражения вычисления (F#).

Функция using

Функция using имеет следующую форму.

using (expression1) function-or-lambda

В выражении using параметр expression1 создает объект, который необходимо освободить.Результатом expression1 (объекта, который необходимо освободить) становится аргумент value для function-or-lambda, представляющего собой либо функцию, ожидающую один оставшийся аргумент типа, который сочетается с результирующим значением 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 jumped 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.Если используется ключевое слово using, метод Dispose вызывается в конце функции или лямбда-выражения; если используется ключевое слово use, метод Dispose вызывается в конце содержащего его блока кода.В общем случае лучше использовать ключевое слово use, а не функцию using.

См. также

Ссылки

IDisposable

Другие ресурсы

Справочник по языку F#