リソース管理:Use キーワードResource Management: The use Keyword

このトピックuse usingでは、リソースの初期化と解放を制御できるキーワードと関数について説明します。This topic describes the keyword use and the using function, which can control the initialization and release of resources.

リソースResources

リソースという用語は、複数の方法で使用されます。The term resource is used in more than one way. はい。リソースは、文字列やグラフィックスなど、アプリケーションで使用されるデータにすることができますが、このコンテキストでは、リソースとは、グラフィックスデバイスコンテキスト、ファイルハンドル、ネットワーク、データベースなどのソフトウェアまたはオペレーティングシステムのリソースを指します。接続、待機ハンドルなどの同時実行オブジェクトなど。Yes, resources can be data that an application uses, such as strings, graphics, and the like, but in this context, resources refers to software or operating system resources, such as graphics device contexts, file handles, network and database connections, concurrency objects such as wait handles, and so on. これらのリソースをアプリケーションで使用するには、オペレーティングシステムまたは他のリソースプロバイダーからリソースを取得した後、リソースの新しいリリースをプールに渡して、別のアプリケーションに提供できるようにします。The use of these resources by applications involves the acquisition of the resource from the operating system or other resource provider, followed by the later release of the resource to the pool so that it can be provided to another application. アプリケーションがリソースを共通プールに解放しないと、問題が発生します。Problems occur when applications do not release resources back to the common pool.

リソースの管理Managing Resources

アプリケーションのリソースを効率的かつ確実に管理するには、リソースを迅速かつ予測可能な方法で解放する必要があります。To efficiently and responsibly manage resources in an application, you must release resources promptly and in a predictable manner. .NET Framework を使用すると、 System.IDisposableインターフェイスを提供してこれを行うことができます。The .NET Framework helps you do this by providing the System.IDisposable interface. を実装System.IDisposableする型にSystem.IDisposable.Disposeは、リソースを正しく解放するメソッドがあります。A type that implements System.IDisposable has the System.IDisposable.Dispose method, which correctly frees resources. 適切に記述されたSystem.IDisposable.Disposeアプリケーションは、リソースが制限されているオブジェクトが不要になったときに、すぐに呼び出されることを保証します。Well-written applications guarantee that System.IDisposable.Dispose is called promptly when any object that holds a limited resource is no longer needed. さいわい、ほとんどの .NET 言語が、簡単に確認するサポートを提供し、F# には例外はありません。Fortunately, most .NET languages provide support to make this easier, and F# is no exception. Dispose パターンをサポートする便利な言語構成要素use usingとして、バインディングと関数の2つがあります。There are two useful language constructs that support the dispose pattern: the use binding and the using function.

バインドを使用するuse Binding

キーワードには、 letバインドの形式に似た形式があります。 useThe use keyword has a form that resembles that of the let binding:

= を使用するuse value = expression

letバインディングと同じ機能を提供しますが、値がスコープDispose外になったときにの呼び出しを値に追加します。It provides the same functionality as a let binding but adds a call to Dispose on the value when the value goes out of scope. コンパイラは値に null チェックを挿入するため、値がnullの場合、へDisposeの呼び出しは試行されません。Note that the compiler inserts a null check on the value, so that if the value is null, the call to Dispose is not attempted.

次の例は、 useキーワードを使用してファイルを自動的に閉じる方法を示しています。The following example shows how to close a file automatically by using the use keyword.

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式のカスタマイズされたバージョンが使用されます。You can use use in computation expressions, in which case a customized version of the use expression is used. 詳細については、「シーケンス非同期ワークフロー、およびコンピュテーション式」を参照してください。For more information, see Sequences, Asynchronous Workflows, and Computation Expressions.

関数の使用using Function

関数usingの形式は次のとおりです。The using function has the following form:

using(expression1)関数または-ラムダusing (expression1) function-or-lambda

式では、expression1 は、破棄する必要があるオブジェクトを作成します。 usingIn a using expression, expression1 creates the object that must be disposed. Expression1 (破棄する必要があるオブジェクト) の結果は、引数、またはラムダになります。これは、によって生成される値に一致する型の1つの残りの引数を期待する関数です。expression1、またはその型の引数を予期するラムダ式。The result of expression1 (the object that must be disposed) becomes an argument, value, to function-or-lambda, which is either a function that expects a single remaining argument of a type that matches the value produced by expression1, or a lambda expression that expects an argument of that type. 関数の実行が終了すると、ランタイムはリソースを呼び出しDispose 、解放します (値がnullの場合を除きます。この場合、Dispose への呼び出しは試行されません)。At the end of the execution of the function, the runtime calls Dispose and frees the resources (unless the value is null, in which case the call to Dispose is not attempted).

次の例ではusing 、ラムダ式を含む式を示します。The following example demonstrates the using expression with a lambda expression.

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関数を使用した式を示しています。The next example shows the using expression with a function.

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

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

関数は、いくつかの引数が既に適用されている関数である可能性があることに注意してください。Note that the function could be a function that has some arguments applied already. 次のコード例はこの処理方法を示しています。The following code example demonstrates this. この例では、文字列XYZを含むファイルを作成します。It creates a file that contains the string XYZ.

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

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

using 関数useとバインディングは、同じことを実現するためのほぼ同じ方法です。The using function and the use binding are nearly equivalent ways to accomplish the same thing. キーワードusingを使用すると、がDispose呼び出されるタイミングをより細かく制御できます。The using keyword provides more control over when Dispose is called. を使用usingするとDispose 、関数またはラムダ式の末尾でが呼び出されuseます。キーワードを使用するDisposeと、が格納されているコードブロックの末尾でが呼び出されます。When you use using, Dispose is called at the end of the function or lambda expression; when you use the use keyword, Dispose is called at the end of the containing code block. 一般に、 using関数の代わりにをuse使用することをお勧めします。In general, you should prefer to use use instead of the using function.

関連項目See also