1

I'm confused by a recent change in the behavior of my WCF IIS application. A week ago, I was able to make a request to my service to a simple "Health" function that incremented a static variable using Interlocked.Increment and returned it. Now, I always get '1' as a return value.

The code in that particular pathway hasn't changed:

[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);
}

Possibly relevant web.config settings:

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

And in IIS, I've configured the AppPool to have a StartMode of AlwaysRunning. But I did that after I discovered this issue and it makes no difference.

I have isolated the issue to NLog. I have a static constructor:

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

The degenerate, new behavior happens with the above static constructor, but not the below code:

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

In short, if I use the NLog Logger to log anything, it appears as if my AppDomain recycles on each request or that .NET is mysteriously determining that my class needs to be recompiled (https://stackoverflow.com/a/8919336/148051). I have even created a Singleton and done all this stuff in the singleton and the behavior is the same. As soon as I use the Logger, the static variables are clobbered.

Can anyone help me understand how to avoid this behavior?

argyle
  • 1,319
  • 2
  • 14
  • 28
  • Have you looked at the app pool's `Idle Time-out (minutes)` property? You should set that to `0` otherwise the app pool will just spontaneously recycle. – Kirk Woll Jun 03 '17 at 02:22

2 Answers2

1

if you are using iis 8 or higher please set your Idle Time-out=0 in order to prevent the app pool recycling. but if you are using iis 7 please take a look at this post:IIS 7.5 - Change Application Pool Start Mode to Always Running

Mohammad
  • 2,724
  • 6
  • 29
  • 55
0

I discovered the answer. I had NLOG writing the log file to the Assembly directory:

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

Once I changed that to a different directory, problem solved. So, apparently, how IIS works is to determine that the types in the app domain need to be recompiled if the application directory is written to.

There may be a way to configure IIS to ignore the log directory, but I was satisfied with moving it to a different location.

argyle
  • 1,319
  • 2
  • 14
  • 28