偶发错误:该文件尚未预编译,因此无法请求

时间:2019-03-21 01:42:29

标签: asp.net

症状:Azure上的ASP.NET Web Forms网站偶尔崩溃,并且所有.aspx页面请求均因此错误而失败。该问题似乎是随机的,并且只会在很长时间内发生一次。该站点可以运行几个月,没有任何问题,然后突然变色,它将停止为任何.aspx页提供服务,并在每个.aspx页请求中给出错误。重新启动网站是唯一的解决方案(或重新部署,这会导致相同的情况)。

这是一个很难调试的问题,因为它是偶发的,我发现的其他答案都无济于事,他们没有解决该站点将长时间部署和运行然后因该错误而崩溃的问题。随机地。最后,我从微软那里得到了一些帮助。

4 个答案:

答案 0 :(得分:5)

根据Microsoft,这是由Web服务器工作进程中的内存压力触发的.Net Framework 4.7.x版本的已知错误引起的。它已在.Net Framework 4.8中修复(目前尚未发布)。我的解决方案只是检查“允许预编译的站点是可更新的”并选中“不合并”选项。

Microsoft的详细信息:

此问题的根本原因与工作进程(w3wp.exe)地址空间上的内存压力有关。在ASP.net中,当.Net Framework检测到我们已超过某个内存压力阈值时,它将继续尝试从内部缓存结构中弹出项目以释放​​空间。经过这样的缓存修剪,属于您的应用程序的程序集将从内存缓存中删除。这将触发一个回调委托,该委托将尝试将内存缓存中的更改反映到磁盘上程序集的缓存中,并将尝试删除从内存中缓存中弹出的.dll程序集。但是,辅助进程仍保留对此文件的引用(打开的句柄),因此删除失败。发生这种情况时,.Net Framework将在程序集旁边创建一个.delete文件,以将其标记为过期。这样可以防止工作进程将文件重新加载到内存缓存中,并导致您看到编译错误。

所有这些缓存处理的原因是错误地将动态程序集插入到ASP.net内存缓存中,该动态程序集是由具有不可更新UI的预编译过程发出的。在此编译过程中,无法更改动态程序集的名称,因为如果对ASP.net Runtime进行了更改,则指示ASP.net Runtime的编译资源所在的二进制文件中的.compiled资源文件不会更改。网站–与使用可更新UI进行的预编译相反,在该版本中,页面的标记可能会发生更改,这会更改.compiled文件,然后更改动态程序集的名称,从而防止重新使用旧名字。

对于来自具有不可更新UI的ASP.net应用程序预编译的程序集,标准是使用特殊属性将它们插入工作进程中的ASP.net内存缓存中,该特殊属性指示缓存管理器,这些条目无法删除。 .Net Framework 4.7.x版本中缺少此属性,并且是导致错误的原因。没有它,修剪缓存时,可以删除程序集,并且由于它们仍在使用中,因此无法从Temporary ASP.net Files文件夹(卷影副本文件夹)中删除它们。因此,这将导致创建.delete文件。在4.7之前的.Net Framework版本中,这不是问题。该产品小组还确认,他们将在即将发布的.Net Framework 4.8版本中解决此问题。

关于此问题,有两种解决方案:

删除4.7.x .Net Framework,然后重新安装4.6.x Framework。

仅在4.7及更高版本的.Net Framework的内部版本中存在缓存错误,因此将其还原为4.6.x版本将使您能够继续工作而不会遇到问题。它们可以保留在4.6.x发行版中,直到今年晚些时候发布.Net Framework 4.8。到目前为止,我还没有该版本产品组的时间表。

增加RAM和专用字节回收限制。 (不适用于Azure Webapp)

当我们看到工作进程内部的内存压力过大时,将在ASP.net中修剪缓存。此内存压力的评估如下:如果您在IIS的应用程序的应用程序池中没有设置回收条件,则ASP.net将认为该阈值是计算机可用总RAM的60%。当辅助进程的专用字节超过此阈值时,内部缓存将被修剪,并且程序集将被弹出,从而导致.delete文件的外观。我建议您与客户合作,尽可能增加受影响最大的服务器可用的RAM内存,并根据托管受影响应用程序的应用程序池上的专用字节设置内存回收。我们可以将此回收限制设置为高于RAM的值,以便确保阈值足够高,以至于工作进程无法达到。

要在应用程序池上设置专用字节回收:

  1. 在受影响的服务器上启动IIS管理器控制台。
  2. 右键单击受影响的应用程序池,然后从显示的上下文菜单中选择“回收”。
  3. 在显示的“回收属性”窗口中,为“私人内存使用(KB)”文本框输入一个值。
  4. 该值应为1.2 *可用RAM,以KB表示。这是一个临时解决方法,一旦发布并安装了新版本的.Net Framework,便应回滚。

安装.Net Framework 4.8预览

您可以尝试安装.Net Framework 4.8的预览版,该预览版现在可以在线下载。但是,这是预览版,您可能会遇到其他问题,直到发布框架后,该问题才得到支持。您还可以选择安装Microsoft的专用修补程序(如果需要此Nand,我会要求我提供此修补程序),该修补程序将更改.Net Framework 4.7.x中发生故障的程序集,以允许将程序集正确插入到缓存中。但是,此私有修补程序未签名,因此将要求我们在服务器上禁用组装符号检查,这可能使客户面临其他安全风险。

在项目预编译选项中,选中“允许预编译站点可更新”和“请勿合并”选项。

该错误仅影响不可更新的预编译二进制文件,因此可以避免该错误,但是启动时间显然受到很大影响。对我而言,此解决方案很简单,并且在4.8版Azure Web服务推出之前可以正常使用。

答案 1 :(得分:0)

如果它以前曾在工作,并且突然收到此错误消息,请尝试在ApplicationPool的高级选项中将“启用32位应用程序”设置为True。

答案 2 :(得分:0)

我只想在这里发帖,因为它可能与其他人有关。我在Azure中运行的ASP.NET Framework 4.7 / 4.8中有一个大型旧项目。

Azure上的页面“实时”编译存在很多问题。我的意思很多。有时,我遇到的页面没有经过预编译,Azure似乎耗尽了所有编译资源,从而导致整个应用程序崩溃。重新启动后,花了8(!!)分钟才可以处理第一击。本地只有30秒。

在Corona期间,我终于有时间转移到.NET Core-所有这些问题立即消失了。

尽管Microsoft表示他们将在很长一段时间内继续支持.NET Framework,但对我来说很明显,Microsoft对该项目不再有任何热情。我与Azure结合使用时遇到的问题很荒谬。

强烈建议尽快迁移。即使是一个大型项目,也没有我以前想象的那么痛苦。

答案 3 :(得分:0)

在偶然的页面上,我有时会遇到同样的问题,该页面突然停止工作。 像这样 https://www.php.net/manual/fr/function.array-filter.php#111091

但是我知道该页面已预先完成 对我来说,“ WORKAROUND”很奇怪。

  1. 进入有问题的服务器中的Temporary ASP.NET Files文件夹,
  2. 搜索0kb删除的文件
  3. 删除它们。

Pre-compile

Solution在回答中解释了为什么会发生这种情况。将尝试升级到4.8,看看是否能解决问题。

*我认为自4.2起,我一直遇到这个问题,并采用了解决方法。 我感到奇怪的是,微软指出是在4.7中引入的。今天,我再次尝试找出问题的根本原因并找到了这个线索。

感谢Eric的努力,感谢您与Microsoft联系并发布了他们的回复。

相关问题