このトピックでは、Windows Communication Foundation (WCF) アクティビティ トレース モデルでの転送について説明します。
転送定義
アクティビティ間の転送は、エンドポイント内の関連アクティビティ内のイベント間の因果関係を表します。 2 つのアクティビティは、これらのアクティビティ間の制御フロー (たとえば、メソッド呼び出しがアクティビティの境界を越える場合) の転送に関連します。 WCF では、サービスでバイトが受信されると、Listen At アクティビティが、メッセージ オブジェクトが作成される Receive Bytes アクティビティに転送されます。 エンドツーエンドのトレース シナリオの一覧と、それぞれのアクティビティとトレースの設計については、「 エンドTo-End トレース シナリオ」を参照してください。
転送トレースを出力するには、次の構成コードで示すように、トレース ソースの ActivityTracing
設定を使用します。
<source name="System.ServiceModel" switchValue="Verbose,ActivityTracing">
転送を使用してエンドポイント内のアクティビティを関連付ける
アクティビティと転送により、ユーザーはエラーの根本原因を確率的に特定できます。 たとえば、コンポーネント M と N でアクティビティ M と N の間でそれぞれやり取りし、M への転送の直後に N でクラッシュが発生した場合、N がデータを M に渡したことが原因である可能性が高いと結論付けることができます。
M と N の間に制御のフローがある場合、転送トレースはアクティビティ M からアクティビティ N に出力されます。たとえば、N は、アクティビティの境界を越えたメソッド呼び出しのために M に対して何らかの処理を実行します。 N は既に存在しているか、作成されている可能性があります。 N が M に対して何らかの処理を実行する新しいアクティビティである場合、N は M によって生成されます。
M から N への転送の後に、N から M への転送が続かない場合があります。これは、M が N で何らかの作業を生成でき、N がその作業を完了した時点を追跡しないためです。 実際、M は N がタスクを完了する前に終了できます。 これは、リスナー アクティビティ (N) を生成して終了する "Open ServiceHost" アクティビティ (M) で発生します。 N から M への転送は、N が M に関連する作業を完了したことを意味します。
N は、M に関係のない他の処理 (たとえば、別のログイン アクティビティからログイン要求 (M) を受信し続ける既存の認証子アクティビティ (N) を引き続き実行できます。
アクティビティ M と N の間に入れ子関係が存在するとは限りません。これは、2 つの理由で発生する可能性があります。 まず、MがNを開始したものの、Nで実行される処理を監視しない場合。次に、Nが既に存在する場合。
転送の例
次に、2 つの転送例を示します。
サービス ホストを作成すると、コンストラクターは呼び出し元のコードから制御を取得するか、呼び出し元のコードをコンストラクターに転送します。 コンストラクターの実行が完了すると、呼び出し元のコードに制御が返されるか、コンストラクターが呼び出し元のコードに戻ります。 これは、入れ子になったリレーションシップの場合です。
リスナーは、トランスポート データの処理を開始すると、新しいスレッドを作成し、処理、制御、およびデータを渡すための適切なコンテキストを受信バイト アクティビティに渡します。 そのスレッドが要求の処理を完了すると、Receive Bytes アクティビティはリスナーに何も渡しません。 この場合、新しいスレッドのアクティビティへの転送はありますが、このアクティビティからの転送はありません。 2 つのアクティビティは関連していますが、入れ子ではありません。
アクティビティ転送シーケンス
整形式のアクティビティ転送シーケンスには、次の手順が含まれます。
新しい gAId の選択で構成される新しいアクティビティを開始します。
現在のアクティビティ ID からその新しい gAId への転送トレースを出力する
TLS で新しい ID を設定する
新しいアクティビティの開始を示す開始トレースを出力します。
元のアクティビティへの戻りは、次の要素で構成されます。
元の gAId に転送トレースを出力する
Stop トレースを出力して、新しいアクティビティの終了を示す
TLS を古い gAId に設定します。
次のコード例は、これを行う方法を示しています。 このサンプルでは、新しいアクティビティに転送するときにブロック呼び出しが行われ、中断/再開トレースが含まれていることを前提としています。
// 0. Create a trace source
TraceSource ts = new TraceSource("myTS");
// 1. remember existing ("ambient") activity for clean up
Guid oldGuid = Trace.CorrelationManager.ActivityId;
// this will be our new activity
Guid newGuid = Guid.NewGuid();
// 2. call transfer, indicating that we are switching to the new AID
ts.TraceTransfer(667, "Transferring.", newGuid);
// 3. Suspend the current activity.
ts.TraceEvent(TraceEventType.Suspend, 667, "Suspend: Activity " + i-1);
// 4. set the new AID in TLS
Trace.CorrelationManager.ActivityId = newGuid;
// 5. Emit the start trace
ts.TraceEvent(TraceEventType.Start, 667, "Boundary: Activity " + i);
// trace something
ts.TraceEvent(TraceEventType.Information, 667, "Hello from activity " + i);
// Perform Work
// some work.
// Return
ts.TraceEvent(TraceEventType.Information, 667, "Work complete on activity " + i);
// 6. Emit the transfer returning to the original activity
ts.TraceTransfer(667, "Transferring Back.", oldGuid);
// 7. Emit the End trace
ts.TraceEvent(TraceEventType.Stop, 667, "Boundary: Activity " + i);
// 8. Change the tls variable to the original AID
Trace.CorrelationManager.ActivityId = oldGuid;
// 9. Resume the old activity
ts.TraceEvent(TraceEventType.Resume, 667, "Resume: Activity " + i-1);