传输

本主题介绍 Windows Communication Foundation (WCF) 活动跟踪模型中的传输。

传输定义

活动之间的传输表示终结点内相关活动中事件之间的因果关系。 当两个活动之间存在控制流(例如方法调用跨越活动边界)时,这两个活动将与传输相关。 在 WCF 中,当通过服务传入字节时,“侦听”活动将转换为“接收字节”活动,消息对象将在“接收字节”活动中创建。 有关端到端跟踪方案及其各自的活动和跟踪设计的列表,请参阅 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 完成其任务之前终止。 这发生在“Open ServiceHost”活动(M)中,该活动启动了侦听器活动(N),随后终止。 从 N 转移回 M 意味着 N 完成了与 M 相关的工作。

N 可以继续执行与 M 无关的其他处理,例如,现有的验证器活动(N),该活动会从不同的登录活动接收登录请求(M)。

嵌套关系不一定存在于活动 M 和 N 之间。这可能是由于两个原因造成的。 首先,当活动 M 不监视在 N 中执行的实际处理时,尽管 M 发起了 N。其次,当 N 已存在时。

传输示例

下面列出了两个传输示例。

  • 创建服务主机时,构造函数将从调用代码获取控制权,或者调用代码将传输到构造函数。 构造函数完成执行后,它将控制权返回到调用代码,或者构造函数将传输回调用代码。 这是嵌套关系的情形。

  • 当侦听器开始处理传输数据时,它会创建一个新线程,并为接收字节活动提供适当的上下文,以便处理、传递控件和数据。 当该线程处理完请求后,“Receive Bytes” 活动不会将任何内容传回给侦听器。 在这种情况下,有传入的新线程活动而没有传出的新线程活动。 这两个活动是相关的,但不是嵌套的。

活动传输序列

格式正确的活动传输序列包括以下步骤。

  1. 开始一个新活动(包括选择新的 gAId)。

  2. 发出从当前活动 ID 到该新 gAId 的传输跟踪

  3. 在 TLS 中设置新 ID

  4. 发出开始跟踪以指示新活动的开始。

  5. 返回到原始活动包括以下内容:

  6. 发出到原始 gAId 的传输跟踪

  7. 发出停止跟踪以指示新活动的结束

  8. 将 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);  

另请参阅