イベントベースの非同期パターンをいつ実装するかの決定
更新 : 2007 年 11 月
イベント ベースの非同期パターンは、クラスの非同期動作を公開するためのパターンを提供します。このパターンを導入すると、.NET Framework は、非同期動作を公開するための 2 つのパターンを定義します。System.IAsyncResult インターフェイスに基づく非同期パターンと、イベントベースのパターンです。このトピックでは、どのような場合にこの 2 つのパターンを実装すればよいかについて説明します。
IAsyncResult インターフェイスを使用した非同期プログラミングの詳細については、「非同期プログラミングのデザイン パターン」を参照してください。
一般原則
一般に、できる限りイベントベースの非同期パターンを使用して非同期機能を公開する必要があります。ただし、イベント ベースのパターンでは満たすことのできない要件もあります。その場合は、イベントベースのパターンだけでなく、IAsyncResult パターンも実装することが必要になることがあります。
メモ : |
---|
イベントベースのパターンを実装せずに、IAsyncResult パターンだけを実装することはまれです。 |
ガイドライン
イベント ベースの非同期パターンを実装する必要のある場合についてのガイドラインを次に示します。
イベントベースのパターンを既定の API として使用して、クラスの非同期動作を公開します。
クラスを Windows フォームなどのクライアント アプリケーションで主に使用する場合は、IAsyncResult パターンを公開しないでください。
要件を満たす必要がある場合にだけ、IAsyncResult パターンを公開します。たとえば、既存の API との互換性を保つために、IAsyncResult パターンを公開することが必要な場合があります。
イベントベースのパターンを公開せずに、IAsyncResult パターンだけを公開しないでください。
IAsyncResult パターンを公開する必要がある場合は、高度なオプションとして公開します。たとえば、プロキシ オブジェクトを生成する場合、IAsyncResult パターンを生成するオプションと共に、既定でイベントベースのパターンを生成します。
IAsyncResult パターンの実装でイベントベースのパターンの実装を構築します。
同じクラスでイベントベースのパターンと IAsyncResult パターンの両方を公開しないようにしてください。イベントベースのパターンは "高レベル" のクラスで公開し、IAsyncResult パターンは "低レベル" のクラスで公開します。たとえば、WebClient コンポーネントのイベントベースのパターンを、HttpRequest クラスの IAsyncResult パターンと比較します。
互換性を保つために必要な場合は、イベントベースのパターンと IAsyncResult パターンを同じクラスで公開します。たとえば、IAsyncResult パターンを使用する API を既にリリースしている場合、下位互換性を保つために IAsyncResult パターンを保持する必要があります。
実装を分離すると結果的にオブジェクト モデルが複雑になり、複雑さが実装を分離する利点を上回る場合は、イベントベースのパターンと IAsyncResult パターンを同じクラスで公開します。イベントベースのパターンの公開を避けるよりも、単一のクラスで両方のパターンを公開する方が適切です。
イベントベースのパターンと IAsyncResult パターンを単一のクラスで公開する必要がある場合、Advanced に設定した EditorBrowsableAttribute を使用して、IAsyncResult パターンの実装を高度な機能としてマークします。これは、IAsyncResult のプロパティやメソッドを表示するためではなく、Visual Studio の IntelliSense などのデザイン環境に対して示します。これらのプロパティやメソッドも完全に使用できますが、IntelliSense を使用する開発者には API のより明瞭なビューが用意されています。
イベントベースのパターンに加え IAsyncResult パターンを公開する際の判断基準
前述のシナリオに基づくイベント ベースの非同期パターンには多数の利点がありますが、欠点もいくつかあります。パフォーマンスが最も重要な要件である場合は、これらの欠点を認識しておく必要があります。
イベントベースのパターンが IAsyncResult パターンと同様には対処できない 3 つのシナリオは次のとおりです。
1 つの IAsyncResult での待機のブロッキング
多数の IAsyncResult オブジェクトでの待機のブロッキング
IAsyncResult での完了のポーリング
イベントベースのパターンを使用してこれらのシナリオに対処できますが、IAsyncResult パターンを使用するよりも煩雑になります。
多くの場合、開発者は一般的に高いパフォーマンス要件のサービスに対して IAsyncResult パターンを使用します。たとえば、完了のシナリオのポーリングは、高パフォーマンスのサーバーの技法です。
さらに、イベントベースのパターンは、作成するオブジェクト (特に EventArgs) の数が多く、スレッド全体にわたって同期するため、IAsyncResult パターンに比べ効率が下がります。
IAsyncResult パターンを使用する場合に従う推奨事項を次に示します。
WaitHandle オブジェクトまたは IAsyncResult オブジェクトのサポートが特に必要な場合にだけ、IAsyncResult パターンを公開します。
IAsyncResult パターンを使用する既存の API がある場合にだけ、IAsyncResult パターンを公開します。
IAsyncResult パターンに基づく既存の API がある場合は、次回のリリースでイベントベースのパターンも公開するよう考慮します。
検証済みの高いパフォーマンス要件をイベントベースのパターンでは満たすことができず、IAsyncResult パターンであれば満たすことができる場合にだけ、IAsyncResult パターンを公開します。
参照
処理手順
チュートリアル : イベントベースの非同期パターンをサポートするコンポーネントの実装
概念
イベントベースの非同期パターンを実装するための推奨される手順