C# 异步并在嵌套调用中等待。未在未进行等待的方法上等待导致IIS崩溃
我一直在网上寻找,我有一些问题,希望这里有人能回答我。我正在尝试解决一个导致IIS崩溃的问题。这个服务呼叫应该是一个火灾和遗忘类型的呼叫。如果失败,我们将抑制并记录异常。因为它是一个长期运行的服务调用,所以它被实现为异步的。当前实现有几个嵌套的方法调用,如下所示:C# 异步并在嵌套调用中等待。未在未进行等待的方法上等待导致IIS崩溃,c#,async-await,c#-5.0,C#,Async Await,C# 5.0,我一直在网上寻找,我有一些问题,希望这里有人能回答我。我正在尝试解决一个导致IIS崩溃的问题。这个服务呼叫应该是一个火灾和遗忘类型的呼叫。如果失败,我们将抑制并记录异常。因为它是一个长期运行的服务调用,所以它被实现为异步的。当前实现有几个嵌套的方法调用,如下所示: // in first service public void PerformService(some params) { // setup and validation DoAction(); } private
// 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)
}
}
}
实际上,我们正处于一个调用PerformService的循环(从0到多次迭代)中,当前出现以下异常:
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
即使我强制在try-catch块中发生异常(以测试我们的错误记录器),它也会被错误记录器正确地捕获和记录。某些线程似乎仍在尝试在请求完成后执行SynchronizationContext.Post。我认为我们不恰当地使用了C#5的async/await,因为FireAndForgetAsync正在进行await,而其他的都没有。所以,我们说我们要等一下,然后离开。http请求结束后,由于没有任何东西可供同步,因此无法将自身同步备份。不太好,因为此完全打开会导致IIS崩溃。我主要是在寻找其他人的意见,因为我不太熟悉C#5中的async/await以及合适的解决方案。由于我们不想等待它完成,因此从FireAndForgetAsync方法中删除wait和async修饰符似乎应该可以解决问题。除非在
任务完成后有事情要做,否则不应该执行wait
。运行lambda。通过执行wait
,您实际上是在请求在返回的任务完成之前将上下文还原为基本上不执行操作
如果您有理由执行等待
(即在任务完成后应该完成的一些工作。运行
lambda),并且您不希望它尝试恢复上下文,那么您可以对从任务返回的任务使用配置等待(false)
请参阅此帖子,以获得一个很好的解释:
这个服务呼叫应该是一个火灾和遗忘类型的呼叫
希望你没有任何重要的代码,因为
[堆栈跟踪]。。。LegacyAspNetSynchronizationContext
红旗legacyapsnetsynchronizationcontext
与async
和await
不能完美配合
请确保您的web.config中有以下设置:
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
以缓解此方法的问题