これを回避するために、Trace.CorrelationManager プロパティの使用をやめました。これらのプロパティの代わりに、Extension クラスに追加したカスタム プロパティを使用します。これで、この拡張機能の ActivityId と LogicalOperationStack を直接変更できるようになりました。これは、Trace.CorrelationManager プロパティを使用するのと同じくらい便利な操作要求の存続期間中にアクセスできます。
プラスとして、リクエストの存続期間中に使用したい他のカスタム プロパティを保存できます。この好例は、サポート性を向上させるためにロギングにも使用できる顧客 ID またはリソース ID です。
using System;
using System.Collections;
using System.ServiceModel;
namespace MyNamespace
{
/// <summary>
/// Class that represents an extension used to store custom data for the life of a WCF OperationContext.
/// </summary>
public class OperationContextExtension : IExtension<OperationContext>
{
/// <summary>The activity id of the operation.</summary>
private Guid activityId;
/// <summary>The logical operation stack of the operation.</summary>
private Stack logicalOperationStack;
/// <summary>
/// Initializes a new instance of the OperationContextExtension class.
/// </summary>
public OperationContextExtension()
{
this.logicalOperationStack = new Stack();
}
/// <summary>
/// Gets the current OperationContextExtension extension from the OperationContext.
/// </summary>
public static OperationContextExtension Current
{
get
{
OperationContextExtension context;
if (OperationContext.Current == null)
{
context = null;
}
else
{
context = OperationContext.Current.Extensions.Find<OperationContextExtension>();
}
return context;
}
}
/// <summary>
/// Gets or sets the activity id for the current operation.
/// </summary>
public Guid ActivityId
{
get { return this.activityId; }
set { this.activityId = value; }
}
/// <summary>
/// Gets the LogicalOperationStack for the current operation.
/// </summary>
public Stack LogicalOperationStack
{
get { return this.logicalOperationStack; }
}
/// <summary>
/// Enables an extension object to find out when it has been aggregated. Called when the extension is added
/// to the System.ServiceModel.IExtensibleObject Extensions property.
/// </summary>
/// <param name="owner">The extensible object that aggregates this extension.</param>
public void Attach(OperationContext owner)
{
// Use this method for request initialization if needed
}
/// <summary>
/// Enables an object to find out when it is no longer aggregated. Called when an extension is removed
/// from the System.ServiceModel.IExtensibleObject Extensions property.
/// </summary>
/// <param name="owner">The extensible object that aggregates this extension.</param>
public void Detach(OperationContext owner)
{
// Use this method for request cleanup if needed
}
}
}
この拡張機能を OperationContext に追加する必要があります。まず、WCF 動作拡張への適切なフックを見つける必要があります。一般的なオプションは、IEndpointBehavior に適用される MessageInspector を使用することです。これを達成する方法についての素晴らしい読み物を次に示します (私の例が役に立たない場合は、クイック検索で多くの有用な例が得られます)。
フックを作成したら、次の行を使用して、できるだけ早く拡張機能を OperationContext に追加します。
// Add an extension object to the current operation context to track custom state across all threads
// for the life of the operation
OperationContext.Current.Extensions.Add(new OperationContextExtension());
これで、コード ワークフローの実質的にどこからでも、ActivityId プロパティと LogicalOperationStack、またはこのクラスで定義したその他のプロパティにアクセスできます。
LogOperation(OperationContextExtension.Current.ActivityId, logMessage);
OperationContextExtension.Current.LogicalOperationStack.Push("Starting 'Nested Activity' 3...");
お役に立てれば!
-モハメッド