本主題描述 Windows Communication Foundation (WCF) 活動追蹤模型中的傳輸。
傳輸定義
活動之間的傳輸代表端點內相關活動中事件之間的因果關聯性。 有兩個活動涉及傳輸,當控制從一個活動流向另一個活動時,例如,方法呼叫跨越活動的界限。 在 WCF 中,當服務上傳入位元節時,接聽 At 活動會傳送至訊息物件建立所在的接收位元組活動。 如需端對端追蹤案例的清單及其各自的活動和追蹤設計,請參閱 端-To-End 追蹤案例。
若要發出傳輸追蹤,請使用 ActivityTracing 追蹤來源上的 設定,如下列組態程式代碼所示。
<source name="System.ServiceModel" switchValue="Verbose,ActivityTracing">
使用傳輸將端點內的活動相互關聯
活動和傳輸可讓使用者以概率方式找出錯誤的根本原因。 例如,如果我們分別在元件 M 和 N 中切換活動 M 和 N,然後當機事件發生在從 N 傳回 M 之後,我們可以得出結論,這可能是因為 N 將數據傳回 M 所致。
當 M 與 N 之間有控制流程時,會從活動 M 發出傳輸追蹤到活動 N。例如,N 會針對 M 執行一些工作,因為方法呼叫跨越活動界限。 N 可能已經存在或已建立。 當 N 是為 M 執行某些工作的新活動時,M 會生成 N。
從 M 到 N 的傳輸可能不會接著從 N 轉回 M。這是因為 M 可以在 N 中繁衍一些工作,而且不會追蹤 N 完成該工作的時間。 事實上,M 可以在 N 完成其工作之前終止。 這會在「Open ServiceHost」活動 (M) 中產生接聽程式活動 (N),然後終止。 從 N 移回 M 表示 N 已完成與 M 相關的工作。
N 可以繼續執行與 M 無關的其他處理,例如,現有的驗證器活動 (N) 會持續接收來自不同登入活動的登入要求 (M)。
巢狀關聯性不一定存在於活動 M 和 N 之間。這可能會因為兩個原因而發生。 首先,雖然活動 M 起始了 N,但 M 並不會監視 N 中執行的實際處理。其次,當 N 已經存在時。
傳輸範例
下列列出兩個傳輸範例。
當您建立服務主機時,建構函式會從呼叫程式代碼取得控制權,或呼叫程式代碼傳送至建構函式。 當建構函式完成執行時,它會將控制權傳回呼叫程式代碼,或建構函式會傳回呼叫程式代碼。 這是一個巢狀關係的案例。
當監聽器開始處理傳輸資料時,它會建立新的執行緒,並將適當的處理上下文交給接收位元組活動,傳遞控制權和數據。 當該線程完成處理要求時,接收位元組活動不會傳回任何訊息給接聽程式。 在此情況下,我們有新的線程活動中有移入,但沒有移出。 這兩個活動是相關的,但不是巢狀活動。
活動傳輸順序
良好建立的活動傳輸序列包含下列步驟。
開始一項新的活動,其中包含選擇一個新的 gAId。
從目前活動標識碼發出該新 gAId 的傳輸追蹤
在 TLS 中設定新的識別碼
輸出開始追蹤以標示新活動的開端。
返回原始活動包括以下項目:
發送傳輸追蹤記錄至原始 gAId
發送「停止追蹤」信號以表示新活動的結束
將 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);