偶发错误:该文件尚未预编译,无法请求 [英] Sporadic error: The file has not been pre-compiled, and cannot be requested

查看:127
本文介绍了偶发错误:该文件尚未预编译,无法请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Symptoms: ASP.NET Web Forms website on Azure sporadically crashes and all .aspx page requests fail with this error. The problem seems random and only happens once in a great while. The site may run for months with no issues then out of the blue it will stop serving any .aspx pages and gives the error on every .aspx page request. A restart of the website is the only solution (or redeploy, which causes the same thing).

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

This was a very difficult problem to debug since it was so sporadic and none of the other answers I found helped, they did not address the problem where the site would deploy and run for long periods of time then crash with this error seemingly randomly. In the end I got some help from Microsoft.

推荐答案

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

According to Microsoft this is caused by a known bug with the .Net Framework versions 4.7.x triggered by memory pressure in the web server worker process. It is fixed in .Net framework 4.8 (not yet released at this time). My solution was simply to check "allowed precompiled site to be updatable" and check the "Do not merge" option.

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

The root cause of the issue is relating to the memory pressure on the worker process (w3wp.exe) address space. In ASP.net, when the .Net Framework detects that we have exceeded a certain memory pressure threshold, it will proceed to try and eject items from the internal caching structures in order to relieve space. Upon such a cache trim, assemblies belonging to your application are removed from the memory cache. This triggers a callback delegate that will try and reflect that changes in memory cache onto the cache of assemblies on disk – and will try and delete the .dll assembly ejected from the in-memory cache. However, the worker process is still keeping a reference to this file (an open handle) and as such, the delete fails. When this occurs, the .Net Framework creates a .delete file next to the assembly to mark it as stale. This will prevent the worker process from loading the file back into memory cache and causes the compilation error you are seeing.

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

The cause of all of this cache processing is an incorrect insertion into the ASP.net memory cache of dynamic assemblies issued from the pre-compilation process with non-updatable UI. In this process of compilation, the names of the dynamic assemblies cannot be changed, as the .compiled resource files which indicate to the ASP.net Runtime where a compiled resource is located (in what binary) do not change if changes are made to the site – contrary to the pre-compilation with updatable UI, where the markup for pages can be subject to change, and this generates changes to the .compiled files and then to the names of the dynamic assemblies, thus preventing the re-usage of the old names.

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

For assemblies that have come from the pre-compilation of an ASP.net application with non-updatable UI, the standard was to insert them into the ASP.net memory cache in the worker process with a special attribute that would indicate to the cache manager that these entries cannot be removed. This attribute is missing in the .Net Framework 4.7.x release builds and is the cause of the error. Without it, when the cache is trimmed, the assemblies can be removed, and since they are still in usage, they cannot be deleted from the Temporary ASP.net Files folder (the shadow copy folder). As such, this results in the creation of the .delete files. This was not an issue in builds of the .Net Framework prior to 4.7. The product group has also confirmed that they have resolved this issue in the upcoming .Net Framework 4.8 release.

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

There are a couple of solutions around this issue:

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

The caching error is only present in builds of the .Net Framework of 4.7 and above, thereby reverting to a 4.6.x version would allow you to continue working without facing the problem. They can remain in the 4.6.x distribution until the .Net Framework 4.8 is released later this year. I do not have a timeline from the product group for this release as of now.

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

The cache is trimmed in ASP.net when we see that the memory pressure is too great inside the worker process. This memory pressure is evaluated as follows: if you do not have a recycling condition set in the application’s application pool in IIS, ASP.net will consider the threshold to be 60 % of the total RAM available to the machine. When the private bytes of the worker process exceed this threshold, the internal cache will be trimmed, and the assemblies will be ejected, causing the appearance of the .delete files. I advise you work with the customer to increase the RAM memory available to their most impacted servers if possible, and also set a memory recycling based on private bytes on the app pool hosting the impacted application. We can set this recycling limitation to a higher value than the RAM so that we can ensure the threshold is high enough not to be reached by the worker process.

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

To set the private bytes recycling on the application pool:

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

安装.Net Framework 4.8预览

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

Install the .Net Framework 4.8 Preview

You can try to install the preview version of the .Net Framework 4.8 which is available for download online now. However, this is a preview version and you may run into other issues which will not be supported until the Framework is released. You can also opt to install a private fix from Microsoft (reach out to me if you want this nand I will request it), which will change the malfunctioning assemblies from the .Net Framework 4.7.x to allow correct insertion of assemblies into the cache. However, this private fix is not signed, and will hence require us to disable assembly sign checking on the server which may expose the customer to other security risks.

该错误仅影响不可更新的预编译二进制文件,因此可以避免该错误,但是启动时间显然受到很大影响.对我来说,此解决方案很简单,并且可以正常工作,直到将4.8推出Azure Web服务为止.

The bug only affects non-updatable precompiled binaries, so this avoids the bug, but startup times are obviously greatly affected. For me, this solution was simple and works fine until 4.8 rolls out for Azure web services.

这篇关于偶发错误:该文件尚未预编译,无法请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆