2017-06-03 6 views
1

WCF IISアプリケーションの動作が最近変更されたことが混乱しています。一週間前、私は、Interlocked.Incrementを使って静的変数をインクリメントして返す、単純な "Health"関数へのリクエストをサービスに要求することができました。今、私は常に戻り値として '1'を取得します。NLOGを使用してIISでホストされているWCFアプリケーションの静的変数

その特定の経路内のコードが変更されていません。

[ServiceContract] 
public interface IApi { 
    [WebInvoke(
     Method = "GET", 
     UriTemplate = "health", 
     RequestFormat = WebMessageFormat.Json, 
     ResponseFormat = WebMessageFormat.Json, 
     BodyStyle = WebMessageBodyStyle.Bare)] 
    [OperationContract] 
    int GetHealth(); 
} 

static int HealthCount = 0; 
public int GetHealth() 
{ 
    return Interlocked.Increment(ref HealthCount); 
} 

関連する可能性のweb.configの設定:

<appSettings> 
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" 
</appSettings> 
... 
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
... 
<modules runAllManagedModulesForAllRequests="true" /> 

そしてIISで、私はのStartModeを持つようにアプリケーションプールを設定したがAlwaysRunningのしかし、私はこの問題を発見した後にそれを行いました。

NLogに問題を切り分けました。私は、静的コンストラクタを持っている:

static Api() 
    { 
     Logger = LogManager.GetCurrentClassLogger(); 
     Logger.Log(LogLevel.Debug, "API Initialized."); 
    } 

縮退、新しい動作は、上記の静的コンストラクタではなく、以下のコードで起こる:私は何かをログに記録するNLogロガーを使用している場合、要するに

static Api() 
    { 
     Logger = LogManager.GetCurrentClassLogger(); 
    } 

あたかもAppDomainが各要求に対してリサイクルしているか、.NETがクラスを再コンパイルする必要があると奇妙に判断したように見えます(https://stackoverflow.com/a/8919336/148051)。私はシングルトンを作成して、シングルトンでこれらすべてのことを行い、その振る舞いは同じです。 Loggerを使用するとすぐに、静的変数がクローバーされます。

誰でも私がこの動作を回避する方法を理解できますか?

+0

あなたは、アプリケーションプールの 'アイドルタイムアウト(分)'プロパティを見ましたか?これを '0'に設定する必要があります。それ以外の場合、アプリケーションプールは自動的にリサイクルされます。 –

答えて

0

私は答えを発見しました。私はNLOGにアセンブリディレクトリにログファイルを書き込ませました:

var logdir = SystemUtils.AssemblyDirectory(typeof(Api)); 

これを一度別のディレクトリに変更すると、問題は解決しました。したがって、明らかに、IISの仕組みは、アプリケーションディレクトリが書き込まれている場合に、アプリケーションドメイン内の型を再コンパイルする必要があるかどうかを判断することです。

ログディレクトリを無視するようにIISを構成する方法があるかもしれませんが、別の場所に移動することに満足しました。

関連する問題