I've been looking online and am have some questions that hopefully someone here can answer for me. I'm trying to solve a problem that's caused IIS crashes for us. This service call is supposed to be a fire and forget type of call. If it fails we suppress and log the exception. Because it's a long running service call it was implemented as asynchronous. The current implementation has a few nested method calls as follow:
// in first service
public void PerformService(some params)
{
// setup and validation
DoAction();
}
private void DoAction()
{
// final setup
OtherService.FireAndForgetAsync(some params);
}
// in the other service (OtherService)
public async Task FireAndForgetAsync()
{
await Task.Run(() =>
{
try
{
// do some long running stuff
}
catch (Exception e)
{
ErrorLogger.LogError(e)
}
}
}
Effectively we're in a loop (from 0 to many iterations) calling PerformService and currently getting the following exception:
System.NullReferenceException: Object reference not set to an instance of an object. at
System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonati onContext) at
System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationCo ntext) at
System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state) at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallb ack callback, Object state) at System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback call back, Object state) at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAct ion(Object state) at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback c allback, Object
Even when I've forced an exception to happen in the try catch block (to test our error logger), it's properly caught and logged by our error logger. It looks like some thread is still trying to do SynchronizationContext.Post after the request is completed. I'm thinking we're improperly using C# 5's async/await in the sense that FireAndForgetAsync is doing an await, but nothing else is. So, we're saying we're going to wait but then just leave. The http request ends and by then it can't synchronize itself back up since there's nothing left to synchronize to. Not good since this full on crashes IIS. I'm mainly looking for other people's input since I'm not very familiar with the async/await in C# 5 and of what a proper solution would be. Since we don't want to wait for it to finish, removing the await and async modifier from the FireAndForgetAsync method seems like it should fix the problem.