2

セッションを使用するようにセットアップされた wcf サービス (IIS でホストされている) があります。うまくいくようです。がApplication_PostAcquireRequestState呼び出されると、セッション ID があります。

私は最終的に次のように使用します(Global.asaxで):

if (Context.Handler is IRequiresSessionState)
{
    log4net.ThreadContext.Properties["sessionId"] = Session.SessionID;
}

それはうまくいくようです。値は log4net プロパティに保存されます。

しかし、サービス操作 (実際の WCF サービス コード) が開始されると、log4net プロパティは再び null になります。

プロパティはスレッドごとに保存されるため ( ThreadContext)、セッションが 1 つのスレッドでセットアップされ、別のスレッドで実行されることを意味しているとしか思えません。私は正しいですか?

log4net プロパティを正しいスレッドで設定する方法はありますか (すべてのサービス操作の開始時に上記の呼び出しを行うことを覚えておく必要はありません)。

4

3 に答える 3

2

はい、IIS は複数のスレッドを使用して複数の WCF 要求を処理する場合があります。詳細については、 http://msdn.microsoft.com/en-us/library/cc512374.aspxを参照してください。

WCF 要求ごとに異なるロガーのインスタンスを使用することを検討してください。

于 2013-05-01T14:25:15.327 に答える
1

カスタム プロパティは文字列である必要はありません。したがって、次のクラスのインスタンスをグローバル コンテキストに格納できます。

public class SessionIdProperty 
{
    public override string ToString()
    {
        // error handling omitted
        return Session.SessionID;
    }
}

このようにして、log4net はSessionメッセージをログに記録するときにオブジェクトに直接アクセスできます。Log4net は、文字列以外のプロパティで ToString() メソッドを呼び出します。

于 2013-05-04T12:29:39.653 に答える
1

WCF がスレッドを変更する可能性がある複数のシナリオがあります。

  1. Global.asx スレッドがサービス呼び出しに使用されることは保証されていません (実際にはそうはなりません)。
  2. 同じセッション中に複数の呼び出しがある場合、同じサービス インスタンスへの呼び出し間でスレッドが変わることもあります。

理論的には、このような状態情報は Operation Context オブジェクトに格納する必要があります。ただし、log4net はスレッド ローカル ストレージを使用するため、扱いにくいソリューションになります。

log4net プロパティを正しいスレッドで設定する方法はありますか (すべてのサービス操作の開始時に上記の呼び出しを行うことを覚えておく必要はありません)。

はい。カスタムIOperationInvokerを作成します。私が知っている最も良い例は、Carlos Figueira のブログです。これをサービス動作として適用する場合、log4net プロパティは常にサービス コードに対して定義する必要があります。

1 つの警告:スレッド ローカル ストレージに追加するときは、必ずクリーンアップしてください。そのため、log4net.ThreadContext.Stacks[].Push() は IDisposable を返します。つまり、Invokeメソッドは次のようになります (不完全でテストされていません)。

public object Invoke(object instance, object[] inputs, out object[] outputs)
{
    using (log4net.ThreadContext.Stacks[key].Push(value))
    {
        return this.originalInvoker.Invoke(instance, inputs, out outputs);
    }
}

「originalInvoker」と呼んでいる理由を理解するには、Carlos のブログを参照してください。非同期操作をサポートする場合は、追加のメソッドを実装する必要があることに注意してください。

于 2013-05-01T15:14:39.983 に答える