Gerenciamento de recursos: a palavra-chave de uso
Este tópico descreve a palavra-chave use
e a using
função, que podem controlar a inicialização e a liberação de recursos.
Recursos
O termo recurso é usado de mais de uma maneira. Sim, os recursos podem ser dados que um aplicativo usa, como cadeias de caracteres, gráficos e similares, mas, nesse contexto, recursos referem-se a recursos de software ou sistema operacional, como contextos de dispositivos gráficos, identificadores de arquivo, conexões de rede e banco de dados, objetos de simultaneidade, como alças de espera, e assim por diante. O uso desses recursos por aplicativos envolve a aquisição do recurso do sistema operacional ou outro provedor de recursos, seguido pela liberação posterior do recurso para o pool para que possa ser fornecido a outro aplicativo. Problemas ocorrem quando os aplicativos não liberam recursos de volta para o pool comum.
Gestão de Recursos
Para gerenciar recursos de forma eficiente e responsável em um aplicativo, você deve liberar recursos prontamente e de forma previsível. O .NET Framework ajuda você a fazer isso fornecendo a System.IDisposable
interface. Um tipo que implementa System.IDisposable
tem o System.IDisposable.Dispose
método, que libera recursos corretamente. Aplicativos bem escritos garantem que System.IDisposable.Dispose
é chamado prontamente quando qualquer objeto que contém um recurso limitado não é mais necessário. Felizmente, a maioria das linguagens .NET fornece suporte para tornar isso mais fácil, e o F# não é exceção. Existem duas construções de linguagem úteis que suportam o padrão de eliminação: a use
ligação e a using
função.
usar Vinculação
A use
palavra-chave tem uma forma semelhante à let
da ligação:
usar expressão de valor =
Ele fornece a mesma funcionalidade que uma let
ligação, mas adiciona uma chamada ao Dispose
valor quando o valor sai do escopo. Observe que o compilador insere uma verificação nula no valor, de modo que, se o valor for null
, a chamada para Dispose
não é tentada.
O exemplo a seguir mostra como fechar um arquivo automaticamente usando a use
palavra-chave.
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."
Várias instâncias de são eliminadas use
na ordem inversa em que são declaradas. Ou seja, o primeiro use
será o último lançado.
Nota
Você pode usar use
em expressões de computação, caso em que uma versão personalizada da use
expressão é usada. Para obter mais informações, consulte Sequências, expressões assíncronas, expressões de tarefa e expressões de computação.
usando a função
A using
função tem a seguinte forma:
using
(expressão1) função-ou-lambda
Em uma using
expressão, expression1 cria o objeto que deve ser descartado. O resultado de expression1 (o objeto que deve ser descartado) torna-se um argumento, valor, para function-or-lambda, que é uma função que espera um único argumento restante de um tipo que corresponde ao valor produzido por expression1, ou uma expressão lambda que espera um argumento desse tipo. No final da execução da função, o tempo de execução chama Dispose
e libera os recursos (a menos que o valor seja null
, caso em que a chamada para Dispor não é tentada).
O exemplo a seguir demonstra a using
expressão com uma expressão lambda.
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."
O próximo exemplo mostra a using
expressão com uma função.
let printToFile (file1 : System.IO.StreamWriter) =
file1.WriteLine("Test output");
using (System.IO.File.CreateText("test.txt")) printToFile
Observe que a função pode ser uma função que já tem alguns argumentos aplicados. O exemplo de código a seguir demonstra isso. Ele cria um arquivo que contém a cadeia de caracteres XYZ
.
let printToFile2 obj (file1 : System.IO.StreamWriter) =
file1.WriteLine(obj.ToString())
using (System.IO.File.CreateText("test.txt")) (printToFile2 "XYZ")
A using
função e a use
ligação são formas quase equivalentes de realizar a mesma coisa. A using
palavra-chave fornece mais controle sobre quando Dispose
é chamada. Quando você usa using
, Dispose
é chamado no final da função ou expressão lambda, quando você usa a use
palavra-chave, Dispose
é chamado no final do bloco de código que contém. Em geral, você deve preferir usar use
em vez da using
função.