One of my .NET apps was having some strange issues. It was attached to an IIS app pool, so it was possible that the app pool was recycling due to some other application’s events or otherwise. I decided to create a listener to detect whenever the app pool was recycling and log what was causing it.
Here’s the class created to listen for recycling events:
public class ApplicationPoolRecycleListener
{
public enum RecycleReason
{
IisReset = 3202,
ReachedProcessingTimeLimit = 5074,
ReachedAllowedRequestLimit = 5075,
ReachedScheduledRecycleTime = 5076,
ReachedVirtualMemoryLimit = 5077,
ReachedPrivateBytesMemoryLimit = 5117,
AdministratorRequest = 5079,
AppPoolConfigurationChange = 5080,
IisConfigurationError = 5081
}
private readonly string _targetApplicationPoolName;
private bool _stopListening;
public Func<EntryWrittenEventArgs, RecycleReason, bool> OnTargetApplicationRecycled { get; set; }
public Func<EntryWrittenEventArgs, RecycleReason, bool> OnNonTargetApplicationRecycled { get; set; }
public ApplicationPoolRecycleListener(string targetApplicationPoolName)
{
_targetApplicationPoolName = targetApplicationPoolName;
_stopListening = false;
}
public void StartListening()
{
var eventLog = new EventLog { Log = "System", EnableRaisingEvents = true };
eventLog.EntryWritten += EventWrittenCallback;
var eventLog2 = new EventLog { Log = "Application", EnableRaisingEvents = true };
eventLog2.EntryWritten += EventWrittenCallback;
while (_stopListening == false) { }
}
private void EventWrittenCallback(object sender, EntryWrittenEventArgs e)
{
var eventId = e.Entry.EventID;
if (Enum.IsDefined(typeof (RecycleReason), eventId))
{
var recycleReason = (RecycleReason)eventId;
if (recycleReason == RecycleReason.IisReset)
{
_stopListening = OnTargetApplicationRecycled?.Invoke(e, recycleReason) ?? false;
}
else
{
if (e.Entry.Message.ToLower().Contains($"serving application pool '{_targetApplicationPoolName.ToLower()}'"))
{
_stopListening = OnTargetApplicationRecycled?.Invoke(e, recycleReason) ?? false;
}
else
{
_stopListening = OnNonTargetApplicationRecycled?.Invoke(e, recycleReason) ?? false;
}
}
}
}
}
Now I was able to debug or log to detect why the recycling was occurring.
Example use:
using System;
using System.Diagnostics;
using System.Net;
namespace EventLogListener
{
class Program
{
static void Main(string[] args)
{
var listener = new ApplicationPoolRecycleListener("StreamingServer")
{
OnTargetApplicationRecycled = (entry, recycleReason) =>
{
// do something
return true;
},
OnNonTargetApplicationRecycled = (entry, recycleReason) =>
{
// do something
return true;
}
};
listener.StartListening();
}
}
}


