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?