InfoRetrieval Web サービス
Leendert Versluijs, Software Engineer
Jeroen Huitink, Infrastructure Engineer
Sander Duivestein, Public Relations
Cap Gemini Ernst & Young
March 19, 2002
日本語版最終更新日 2003 年 6 月 6 日
要約 : InfoRetrieval Web サービスの機能とデザインについて説明します。InfoRetrieval Web サービスは、不動産 Web アプリケーション Jaggle のコンポーネントの 1 つであり、ローカル データベースや外部の Web サイトなどの外部のソースから、詳細な製品情報を取得します。
目次
概要説明
必要条件
分析とデザイン
例
InfoRetrieval クラス
設計方針
便利な機能
概要説明
InfoRetrieval Web サービスは、Matching Web サービスによって生成された製品 ID に基づく顧客への製品情報を提供します。次の図は、不動産 Web アプリケーション Jaggle® の全体的なアーキテクチャにおける InfoRetrieval Web サービスの位置付けを表しています。
図 1. 不動産アプリケーション Jaggle の中の InfoRetrieval Web サービス
製品情報は、2 段階で取得されます。最初に、顧客が要求に一致する製品の概要一覧を受け取ります。これは、一覧取得と呼ばれます。次に、この一覧から特定の製品を選択した後、顧客は選択した製品に関する詳細情報を受け取ります。これは、詳細取得と呼ばれます。
このプロセスには、いくつかの Web サービスのやり取りが伴います。Matching Web サービスの一致プロセスにより、製品 ID の一覧が提供されます。製品 ID は、Web サイトから InfoRetrieval Web サービスに送られます。InfoRetrieval Web サービスは、最初に、一覧取得の形式で製品情報を返します。次に、詳細取得の形式で外部の Web サービスから取得したデータなどの詳細情報を返します。
InfoRetrieval Web サービスは、ローカルな製品情報データベース (内部情報) または外部の Web サイトなどの外部ソース (外部情報) から、特定の製品に関する詳細情報を取得することができます。NeighbourhoodInfo と ShoppingInfo Web サービスを使用して、外部情報を取得することもできます。
InfoRetrieval Web サービスにより取得されたこの詳細な製品情報は、外部の Web サイト上の静的 HTML として、またはローカルな SQL データ ソース内のデータとしてなど、さまざまな形式で格納することができます。ただし、InfoRetrieval Web サービスにより Web サイトに返された取得データは、常に XML データセット形式で格納されます。必要なデータを解釈するのは、受信側 (この場合は Web サイト) になります。
必要条件
InfoRetrieval Web サービスの必要条件は、ビジネス文書から引き出されます。InfoRetrieval Web サービスには、以下の機能が要求されます。
- Matching Web サービスと内部または外部の情報の橋渡しをします
- ローカルで使用可能なデータを認識します
- 外部からのデータの取得先を認識します
- 外部の Web サービスと通信します
最後の必要条件は、InfoRetrieval Web サービスが、外部の Web サイトから HTML ページを集めることにより、外部のデータを収集できる必要があることを意味します。これは、アクセス可能な外部の Web サービスを呼び出すことにより行われます。
分析とデザイン
ユース ケース
InfoRetrieval Web サービスの主役は、Web サイトのソフトウェア部分です。次の図は、Web サイト アクタと InfoRetrieval Web サービスとのやり取りのユース ケースの概要です。
図 2. Web サイト アクタと InfoRetrieval Web サービスとのやり取りのユース ケース
アクティビティ図
次のアクティビティ図は、情報取得プロセスの概要を表しています。この図は、ユース ケース内のアクティビティの詳細をカバーしています。Web サイト アクタが情報取得プロセスを起こし、このプロセスのワークフローを促進します。
図 3. 情報取得プロセスのアクティビティ
クラス図
次の 2 つの UML (Unified Modeling Language) クラス図は、InfoRetrieval Web サービスのクラスおよびクラス間の関係の概要を示すオブジェクト モデルを表しています。各オブジェクトは、ファサード層、ビジネス ロジック層、およびデータ アクセス層に対応します。このモデル内のオブジェクトについては、この後の「InfoRetrieval のクラス」で詳しく説明します。
図 4. ファサードおよびビジネス ロジック層のクラス
図 5. データ アクセス層のクラス
シーケンス図
次の図は、情報取得プロセスのシーケンスを示しています。パブリック関数のみが表示されています。
図 6. 情報取得プロセスのシーケンス
データ モデル
製品情報を取得する場合は、メタデータ情報を含むテーブルのグループを使用します。次の図は、InfoRetrieval Web サービスが使用するデータ モデルを表しています。
図 7. InfoRetrieval Web サービスのデータ モデル (拡大するには画像をクリックしてください)
メタデータは、Product、Values、および ForeignAttributes という名前のテーブルに格納されます。要求される製品の各種類に対するローカル ストア テーブルもあります。ローカル ストア テーブルはそれぞれ製品の種類を表し、特定の製品情報が含まれます。ローカル ストア テーブルは、データ モデルのメンバですが、動的な (事前に定義されていない) テーブルです。
たとえば、図 7 には、2 つのローカル ストア テーブル (RealEstate (不動産アプリケーション Jaggle で使用) と Weather) が示されています。RealEstate テーブルには、特定の住宅関連情報が含まれており、Name、Location、Founder、Turnover の各属性によって表されます。次のセクションでは、データ モデルのテーブルについて詳しく説明します。
Product テーブル
各製品 (たとえば、住宅、ローン、抵当権) は、Product テーブルに格納されます。固有の ID を指定するには、PID (製品 ID) と名付けられた グローバル一意識別子 (GUID) フィールドを使用します。このテーブルには、Name と呼ばれる説明フィールドも含まれています。このフィールドには自然言語でオブジェクトが記述されます。また、LocalStore というフィールドには、ローカル ストア テーブルの名前が含まれています。詳細に要求する場合は、必要なすべてのフィールドを選択します (SELECT * FROM Products)。概要一覧を表示するには、以下で説明するように、Values テーブルに含まれる属性のみが考慮されます。
Values テーブル
このテーブルには、ローカル ストア テーブルに関連する情報が含まれます。列には、ID、PID (製品 ID)、AID (外部属性を表します)、Data フィールドが含まれます。AID フィールドが空の場合、レコードは、要求された製品に対応するローカル ストア テーブルの内部フィールドに関連します。それ以外の場合は、外部の Web サービスの ID です。その場合、Data フィールドには必要なパラメータが格納されます。
内部フィールドは一覧情報として使用されます。そのため、製品の概要一覧を要求すると、これらの列がローカル ストア テーブルから返されます。
ForeignAttribute テーブル
ForeignAttribute テーブルには、取得する外部データ (外部情報) に関連する情報が含まれます。このテーブルには、AID フィールドのほかに、Name フィールドと Type フィールドが含まれます。Type フィールドには、返される外部のデータの種類が示されます。Retrieval フィールドには、呼び出す Web サイトが示されます。これは文字列です。Retrieval フィールドには、呼び出す Web サービスの HTTP Get 要求が含まれます (これは URL を含む文字列です)。各変数には、リテラル シーケンス [%] が含まれます。[%] 文字列は、該当する変数の値によって置き換えられます。
ローカル ストア テーブル
ローカル ストア テーブルには、1 つ以上の使用可能な属性によって表される、特定の製品の詳細情報が含まれます。これらは、内部データ (内部情報) またはローカルの属性です。
一覧取得と詳細取得
一覧取得と詳細取得の違いは、Values テーブルに格納されるデータに依存します。AID フィールドの値が NULL の場合、すべてのインスタンスは、ローカル ストア テーブルの属性を参照します。対応する属性の名前は、Data フィールドに格納されます。そのため、一覧取得の選択結果セット (ここから、詳細情報を確認する製品を選択します) については、以下の手順を使用します。
- 製品の名前と情報が格納されるローカル ストア テーブルを選択します
- 列の名前を持つ結果セットを選択します
- 要求された製品の種類に関する情報を選択します
以下のセクションでは、この手順の例を示します。
例
0001 という製品 ID (PID) 値を持つ製品項目 (住宅) を考えます。Product テーブルは、以下のようになります。
表 1. Product テーブル
PID | Name | Localstore |
---|---|---|
0001 | House1 | RealEstate |
... | ... | ... . |
製品の詳しい情報は、RealEstate テーブルに格納されます。RealEstate テーブルは、以下のようになります。
表 2. RealEstate テーブル
Name | Location | Founder | Turnover |
---|---|---|---|
House1 | 2nd Street | Smith | 5 |
... | ... | ... | ... |
Values テーブルは、以下のようになります。
表 3. Values テーブル
ID | PID | AID | Data |
---|---|---|---|
1 | 0001 | NULL | Name |
2 | 0001 | 01 | |
3 | 0001 | NULL | Location |
... | ... | ... | ... |
Values テーブルの 1列目と 3 列目のレコードの Data フィールドには、RealEstate テーブルの Name 属性と Location 属性が表示されます。2 列目のレコードの Data フィールドには外部属性が表示され、AID フィールドには外部属性 ID が含まれます。
表 4. ForeignAttribute テーブル
AID | Name | Type | Retrieval |
---|---|---|---|
01 | Photograph | Picture | "http://..." |
... | ... | ... | ... |
Type フィールドでは属性を決定します。Retrieval フィールドには、属性の値を提供する外部 Web サービスへアクセスするための URL が含まれています。顧客がある製品についてリスト検索選択の結果設定と詳細情報の結果設定の両方を選択した場合、次のステートメントが用いられます。
はじめに、検索対象の製品のローカル ストア テーブルを見つけます。
SELECT Name, Localstore FROM Product WHERE PID = 0001
製品のローカル属性を検索します。
SELECT Data FROM Values WHERE PID = 0001 AND AID IS NULL
リスト検索では、必要なローカル属性の値、例えば、Name と Location を選択します。
SELECT Name, Location FROM RealEstate WHERE PID = 0001
詳細検索では、ローカル ストア テーブルの詳細は外部詳細情報と統合されます。ローカル ストア テーブルの詳細は、以下の通りです。
SELECT RealEstate.* FROM RealEstate WHERE Name = 'House1'
外部詳細情報では、はじめに外部属性の候補が検索され、情報の格納場所である外部 Web サービスから検索された値が返されます。
SELECT Data FROM Values WHERE PID = 0001 AND AID IS NOT NULL
SELECT ForeignAttribute.* FROM ForeignAttribute WHERE ForeignAttributeAID = 01
InfoRetrieval クラス
すべての InfoRetrieval クラスは Jaggle.InfoRetrieval 名前空間の一部です。次の図は、InfoRetrieval Webサービスの様々な機能を持つ層と、それぞれのクラスの実装を行う対応コンポーネントを示しています。
図 8. クラス実装を行うそれぞれの層と対応コンポーネント
次の章では、各クラスについて簡単に説明します。
ファサード層
InfoRetrievalFacade クラス
InfoRetrievalFacadeクラスは、他のクラスがこの Web サービスへアクセスするのに用いる主要なインターフェイスです。クラスへのアクセスは、異なる Web サービスなど、どのタイプのアプリケーションまたはコンポーネントからも実行できます。次の表は、 InfoRetrievalFacade クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。
表 5. BisinessFacade クラスの関数
関数名 | 関数のスコープ | 引数 | 戻り値 | 説明 |
---|---|---|---|---|
RetrieveInfo | Public | ByVal InfoRequestXML as string | String | 要求された製品の概要または詳細情報を検索し、結果を XML 形式で返します。 |
RetrieveSchema | Public | ByVal InfoRequestXML as string | String | 要求された製品の概要または詳細情報の XML スキーマを検索します。 |
ビジネス ロジック層
brInfoRetrieval クラス
ビジネス ルールの層は InfoRetrieval Web サービス サブシステムのビジネス ロジックをカバーする brInfoRetrieval と呼ばれるビジネス ルール クラスを含む 1 つのコンポーネントを定義します。ビジネス ルールはデータセットと共にロジックを実行します。この場合、データセットはデータ アクセス 層によって検索され、接続切断された XML オブジェクトになります。実装されたビジネス ルールは主にデータセットの頂点の薄い層上にあり、ファサード層にその下にあるデータへのアクセスを提供します。
次の表は brInfoRetrieval クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。情報検索の手順についての詳しい説明は、Data Model の章で述べられています。
表 6. brInfoRetrieval クラスの関数
関数名 | 関数のスコープ | 引数 | 戻り値 | 説明 |
---|---|---|---|---|
GetCodes | Private | String | LocalStore テーブルの情報を検索するために、where 節を生成します。 | |
GetDetailData | Private | String | 製品のメタデータに記述されている通りに詳細情報を検索します。 | |
GetInfoRequestType | Private | String | Detail (詳細) と List (リスト)、どちらの要求かを定義します。 | |
GetRequestType | Private | String | 情報を検索するために製品を定義します。 | |
GetSelectionData | Private | String | 製品のメタデータに記載されている通りに概要 (List) 情報を検索します。 | |
RetrieveInfo | Public | ByVal InfoRequestXML as string | String | 要求の型を定義し、適切な関数を呼び出します。 |
RetrieveSchema | Public | ByVal InfoRequestXML as string | String | 要求された製品の概要または詳細情報の XML スキーマを検索します。 |
データ アクセス層
daSQLInfoRetrieval クラス
daSQLInfoRetrieval クラスは、単にビジネス層のコンポーネントからの要求を待っている、ステートメントのないコンポーネントのことです。 daSQLInfoRetrieval クラスは下の層のデータベースからデータをできるだけ速く検索する役割があります。検索されたデータは接続切断された XML データセットとして上の層に渡されます。次の表は daSQLInfoRetrieval クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。
表 7. daSQLInfoRetrieval クラスの関数
関数名 | 関数のスコープ | 引数 | 戻り値 | 説明 |
---|---|---|---|---|
BuildDBConn | Private | SQLConnection | データベースの接続を初期化します | |
GetDataSet | Public | ByVal SQLCommand as string, ByVal DataSetName as string | DataSet | コマンドを実行し、結果のデータセットを返すための一般的な手続きです。 |
New | Public | コマンド オブジェクトとその接続を初期化します。 |
DynamicWebservice アセンブリ
DynamicWebservice アセンブリは、3 つの異なるクラス、ContentUtility、DynamicWebService、ThreadManager および ContentUtility.Conversion と呼ばれる埋め込みストラクチャを提供します。これらのクラスが、外部 Web サービスの呼び出しを可能にします。DynamicWebService クラスと ThreadManager クラスは同期をはかりながら外部 Web サービスへアクセスし、データを取得する役割があります。brInfoRetrieval クラスは DynamicWebService クラスと ThreadManager クラスのインスタンスを生成する役割と、データ モデルへアクセスして解読する役割があります。各外部属性ごとに DynamicWebService クラスのインスタンスが生成されます。すべての DynamicWebService オブジェクトは 1 つの配列に格納されると同時に、ThreadManager クラスのインスタンスとして追加されます。
DynamicWebService インスタンスを ThreadManager に追加するには、TreadStart デリゲードを作成し、それによって追加したい DynamicWebService インスタンスの StoreResult メンバーを呼び出します。ThreadManager の StartAllThreads メンバーが呼び出されると、追加したスレッドが実行され、すべての外部データ検索が並行的に実行されます。WaitForAllThreads メンバーを呼び出すことによって、すべてのスレッド処理が完了し、すべての外部データが GetResult を呼び出すだけで DynamicWebService から検索する準備が整っていることを確認できます。そして、それと同期をはかって ThreadManager クラスは StartAllThreads を実行してデータを取得し WaitForAllThreads メソッド (並行処理) がこれに続きます。次の章では、クラスと埋め込みストラクチャについて説明します。
ContentUtility クラス
このクラスには、Web サービスへ動的なアクセスをする場合に実行される様々な関連性のないアクションが含まれています。次の表は、 ContentUtility クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。
表 8. ContentUtility クラスの関数
関数名 | 関数のスコープ | 引数 | 戻り値 | 説明 |
---|---|---|---|---|
FromString | Public | String Descr | Types | |
FromEnum | Public | Types type | String | 列挙法によって、その列の説明を返します。 |
FromType | Public | Object type | Types | 変数の型に基づいて適切な列挙値を返します。 |
ToArray | Public | Params object[] input | Object[] | 1 つの配列に対し複数の引数を変換します。 |
ReplaceTokens | Public | String mask, object[] values | String | マスク内で生成されたすべての "[%]" 列を対応する値の要素の列表現に置き換えます。一方が先になくなった場合は、置き換えは停止し、エラーも返されません。結果の列のみが返されます。
[Private] |
ContentUtility.Conversion 埋め込みストラクチャ
ContentUtility クラスには ContentUtility.Conversion 埋め込みストラクチャが含まれています。 ContentUtility クラスは形式 (列挙法として) と列挙法で記述された列の値の間の関係を維持しています。次の表は ContentUtility.Conversion クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。
表 9. ContentUtility.Conversion 埋め込みストラクチャの関数
関数名 | 関数のスコープ | 引数 | 戻り値 | 説明 |
---|---|---|---|---|
Conversion | Public | ContentUtility.Types type, string str | ストラクチャを初期化します。 |
DynamicWebService クラス
このクラスは Web サービスを動的に呼び出すのに役立ちます。プリミティブ型データのみを検索し、XmlDocument と XmlDataDocument は列を通じて検索されます。次の表は DynamicWebService クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。
表 10. DynamicWebService クラスの関数
関数名 | 関数のスコープ | 引数 | 戻り値 | 説明 |
---|---|---|---|---|
DynamicWebService | Public | String URL | インスタンスを生成するコンストラクタは、マルチスレッド シナリオ内では使用されません。HTTP Get 列を渡し、各変数を [%] (カッコも含む) と置き換えてください。Web サービスが呼び出されると、これらは変数の値と置き換えられます。 | |
DynamicWebService | Public | URL, System.Object type, object[] values | このコンストラクタは、マルチスレッド シナリオでも作動します。パラメータなしで StoreResultを使用することができます。 | |
DynamicWebService | Public | URL, InfoRetrieval.DataAccess.DynamicWebService.ContentUtility.Types type, object[] values | スレッド実行時に使用されるコンストラクタです。 | |
GetBoolResult | Public | Boolean | Boolean を返す Web サービスを呼び出します。 | |
GetByteResult | Public | Byte | byte を返す Web サービスを呼び出します。 | |
GetCharResult | Public | Char | char を返す Web サービスを呼び出します。 | |
GetDecimalResult | Public | Decimal | decimal を返す Web サービスを呼び出します。 | |
GetDoubleResult | Public | Double | double を返す Web サービスを呼び出します。 | |
GetFloatResult | Public | Single | float を返す Web サービスを呼び出します。 | |
GetIntResult | Public | Int32 | integer を返す Web サービスを呼び出します。 | |
GetLongResult | Public | Int64 | long を返す Web サービスを呼び出します。 | |
GetResult | Public | Object | 前の呼び出しで格納された値を StoreResult に戻します。 | |
GetResult | Public | Object type, object[] values | Object | このバージョンでは、使用する戻り値の型と変数を指定するだけで、結果を 1 度に検索することができます。 |
GetResult | Public | ContentUtility.Types type, object[] values | Object | このオーバーロードは、予測される戻り値の型を伝えるのに異なる方法を使用しますが、オブジェクト GetResult (object type, object[] values) に似ています。 |
GetResult | Protected | Boolean y | Object | 特定の戻り値の型にリンクした方法を使用して、結果を検索し、値を返します。 |
GetSByteResult | Public | SByte | sbyte を返す Web サービスを呼び出します。 | |
GetShortResult | Public | Int16 | short を返す Web サービスを呼び出します。 | |
GetStringResult | Public | String | 列を返す Web サービスを呼び出します(XML データを返すのにも使用されます)。 | |
GetUIntResult | Public | UInt32 | unsigned integer を返す Web サービスを呼び出します。 | |
GetULongResult | Public | UInt64 | unsigned long を返す Web サービスを呼び出します。 | |
GetUShortResult | Public | UInt16 | unsigned short を返す Web サービスを呼び出します。 | |
GetXmlDataDocResult | Public | XMLDataDocument | XmlDataDocument を取得します。(ここで再構築をするために、Web サービスは列としてドキュメントを返す必要があります。したがって、XmlDataDocument を直接返す Web サービスへアクセスすることはできません) | |
GetXmlDocResult | Public | XMLDocument | GetXmlDataDocResult() についての説明を参照してください。 | |
StoreResult | Public | Object type, object[] values | 適切な戻り値の型と変数を渡すと、StoreResult は結果を取得し、内部に格納します。 | |
StoreResult | Public | ContentUtility.Types type, object[] values | これは戻り値の型を指定するもう 1 つの方法ですが、StoreResult (object type, object[] values) と同一のものです。 | |
StoreResult | Public | 既知の型と変数に基づいて、結果を取得します。(スレッド内で実行されている時に使用されますが、このメソッドを呼び出す前に型と変数を指定する必要があります。指定していないと、結果が定義されず、例外コードが返されます。StoreResult はスレッドセーフです) |
ThreadManager クラス
このクラスは 0 から n 個のスレッドを保有しており、同期でこれらを使用することができます。次の表は ThreadManager クラスの関数の名前、スコープ、引数、戻り値、および簡単な説明の一覧です。
表 11. ThreadManager クラスの関数
関数名 | 関数のスコープ | 引数 | 戻り値 | 説明 |
---|---|---|---|---|
AddThread | Public | System.Threading.ThreadStart startWith | Boolean | スレッドを追加せず、threadstart デリゲードになります。重複はチェックしません。 |
IsThreadRunning | Public | Int32 index | Boolean | 特定のスレッドが実行されているかどうか知るには、この関数を呼び出します。 |
StartAllThreads | Public | 必要な数の threadstarts を追加した後にこのメンバーを呼び出すと、追加した threadstarts を 起動します。(追加した時点ではスレッドは起動しません。起動するには呼び出す必要があります) | ||
ThreadManager | コンストラクタ | |||
WaitForAllThreads | 結果を検索する前に、すべてのスレッドがこのメソッドを使用してすべて終了するまで待つことができます。(まだタイムアウトになったことはありません) | |||
WaitForThread | Int32 Index | 特定のスレッドが終了するのを待ちます。(まだタイムアウトになったことはありません) |
デザインの決定
ForegnAttribute テーブルの Type フィールド
コアの .NET データ型を除いて、オブジェクトの整列はまだ行われません。コアのデータ型とは別に、2 つの追加形式、XmlDocument と XmlDataDocument を使用することができます。これらオブジェクトの移行は列として移行し、その列からオブジェクトを再構築するかたちでシュミレートされます。ForeignAttribute テーブル内の Type フィールドはこの情報を含んでおり、次の値のうちどれか 1 つを含む必要があります。
- XmlDataDocument
- XmlDocument
- Bool
- Byte
- Char
- Decimal
- Double
- Float
- Int
- Long
- Sbyte
- Short
- String
- Uint
- Ulong
- ushort
効果的にデータの移行を行うためには、1 つの列のみを使用します。(列では、大文字と小文字は区別されます)列は XmlDocument または XmlDataDocument の DuterXml プロパティに対応しているので、Web サービスは列の値をこれらの変数に返す必要があります。この列からの制約によって、XmlDocument または XmlDataDocument が生成されることがあります。InfoRetrieval Web サービスでは、この機能は DynamicWebService クラスの GetResult メソッドによって実装されます。DynamicWebService クラスは XmlDocument または XmlDataDocument の戻り値の型を有しています。
プログラミング言語
InfoRetrieval Web サービスを構築した 2 者の開発者は異なるバックグランドを持っており、それぞれ異なる言語を選択しています。双方が .NET にとって必須であったため、実装をシェアするのに問題はありませんでした。DynamicWebService アセンブリは C# で構築され、もう一方の部分は Microsoft® Visual Basic® .NET で構築されました。このように InfoRetrieval Web サービスを分割することで、他の Jaggle コンポーネントとのインターフェイスが可能になり、Web サービスの動的アクセスとは独立して、複数のスレッドを使用した開発とテストができるようになりました。
魅力的な機能
GetDetailData 関数
この関数を使用して、新規のXML 列をその他いくつかのXML 列から構築することができます。このように、1 つのXML 列が別のXML 列へインポートされます。
DynamicWebService クラス
最も魅力的な機能は、as-is のオブジェクト ビヘイビアです。Web サービスへのアクセスするためにWeb サービスについて特に学んだり記憶する必要がないよう、同一のオブジェクトを使用しています。また、C 言語の主要なセクションの使用も、驚くほどクリーンで簡単にできます。
ThreadManager クラス
ThreadManager は C言語の魅力的な機能のいくつかを発揮することができます。例えば、スレッドのためのデリゲードを使って、SDK 関数を使用した場合よりはるかに優れたオブジェクト指向コードを作成することができます。次に、FOR EACH ステートメントを使用すると (C または C++ で通常どおり明示的なコーディングを行う代わりに) 必要なコードの行が減り、エラーが起こりにくくなります。そして最後に、共通言語ランタイム (CLR) の素材の豊富さも魅力です。 ThreadManager は CLR 内にすでに多くの素材を有しています。コードを書きテストするまでの時間が短縮でき、再利用も非常に簡単です。
すべてのクラス
すべてのクラスは C 言語によって記述されていますが、Visual Basic .NET の豊富なクラスを使用しても問題はありません。