7

PerSession/WCFサービスの型コンストラクターが2回呼び出された理由を理解できません。ConcurrencyModeですMultiple。同じWCFサービスメソッド呼び出しを実行する5つの同時クライアントを起動するだけで、ログにstaticコンストラクターが2回呼び出されたことがわかります。1回目と3秒後にもう1回呼び出されましたProcessId/ThreadId。コンストラクター自体にもWCFトレースログにも例外はありません。コンストラクターの実行時間は、ログごとに最大10ミリ秒です。この結果、すべての静的フィールドが想定どおりにすべてのサービスインスタンス間で共有されるわけではなく、5つのクライアント接続の場合、5つのサービスと2つの異なる静的コンテキストがあるため、静的フィールドの変更がすべてのサービスに反映されるわけではありません。

複数のサービスインスタンス間で共有される静的キャッシュに依存しているため、この問題は多くのことを混乱させます。

サービスはでホストされていIISます。IISは再起動せず、AppPoolはこの時間間隔でリサイクルします。

[AspNetCompatibilityRequirements(RequirementsMode =
  AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(
  InstanceContextMode = InstanceContextMode.PerSession, 
  IncludeExceptionDetailInFaults = true, 
  ConcurrencyMode = ConcurrencyMode.Multiple)]
public class WcfService
{ 
    private static readonly ILog logger;
    private static volatile bool typeInitialized;

    static WcfService()
    {
        try
        {
            // Here is typeInitialized is false in both calls
            logger = LogManager.GetLogger("LogName");

            logger.InfoFormat("[PID:{0}] [THID:{1}] BEGIN Static constructor",
               Process.GetCurrentProcess().Id,
               Thread.CurrentThread.ManagedThreadId);
        }
        catch (Exception exception)
        {
           logger.Error("error on type construction stage", exception);
        }
        finally
        {
            logger.InfoFormat("[PID:{0}] [THID:{1}] END Static constructor",
               Process.GetCurrentProcess().Id,
               Thread.CurrentThread.ManagedThreadId);               
           typeInitialized = true;
        }
    }
}
4

1 に答える 1

6

IISを使用してサービスをホストしていると仮定すると、単一のAppDomainのスピンアップのみを許可するようにプロセスを明示的に構成しない限り、これは正常な動作です。

実行中のプロセスのリストを見ると、ログ内の各プロセスIDが、個別のアプリドメインをホストしているw3wp.exeのコピーに対応していることがわかります。

于 2012-12-25T14:18:32.610 に答える