Asp.net:在运行时重新编译动态编译的Ascx文件

时间:2018-11-19 12:56:11

标签: c# asp.net iis dynamic compilation

我们的ASP.NET Web应用程序具有一个表单编辑器,用户可以在其中通过将用户控件拖放到页面上并为每个用户控件设置各种属性来创建自己的页面。当最终用户然后在运行时打开该页面时,将根据该配置将用户控件放置在页面上。

编辑器还包含一个业务规则引擎,用户可以在其中创建简单的if-then-else语句,以根据业务逻辑指导页面流。例如,用户可以创建规则“如果Data.Customer.DateOfBirth等于Today,则HappyBirthdayScript可见”,其中HappyBirthdayScript是用户控件的实例。然后,由lambda表达式树编译这些业务规则,然后将它们缓存一天以提高性能。

现在,我们的一位客户遇到的问题是,通常在非高峰时段(午夜之后),但有时甚至在白天的高峰时段,ASP.NET似乎重新编译了动态生成的dll,其中一个或多个ascx文件。这会导致与此类似的错误:

  

System.InvalidCastException:[A] ASP.ui_controls_scripting_ascx无法   强制转换为[B] ASP.ui_controls_scripting_ascx。类型A源自   'App_Web_scripting.ascx.cb748d43.1ce9kuug,版本= 0.0.0.0,   文化=中性,PublicKeyToken =空”,位于“默认”上下文中   位置'C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Temporary   ASP.NET   文件\ root \ a3b6cf39 \ a9985cbd \ App_Web_scripting.ascx.cb748d43.1ce9kuug.dll”。   类型B源自“ App_Web_scripting.ascx.cb748d43.e6qrsk0w,   版本= 0.0.0.0,文化=中性,PublicKeyToken =空'在上下文中   位置为“默认”   'C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \临时ASP.NET   文件\ root \ a3b6cf39 \ a9985cbd \ App_Web_scripting.ascx.cb748d43.e6qrsk0w.dll'

之所以引起此异常,是因为缓存的已编译业务规则中的脚本用户控件类型与临时ASP.NET文件中新的重新编译的dll中的脚本用户控件类型不同。编译后的表达式树将用户控件强制转换为其指定的Type,以访问其属性,而不必使用速度较慢的Reflection。

当您检查此临时文件夹时,旧的和​​新的dll仍然存在。应用程序池回收显然解决了该问题,因为在丢弃缓存时将重新编译业务规则。

在每台负载平衡的服务器中的每一个或每两天发生一次。两台服务器的应用程序池都设置为每天凌晨3:33回收。我们的其他客户都没有这个问题。它也不会每次都在同一时间发生,并且不会在同一控件中发生。因此,我很想找出造成这种情况的根本原因。

作为一种解决方法,我们将为该客户提供一个特殊的版本,在该版本中,我们将使用不可更新的UI通过网络发布功能预编译所有UI组件,以试图阻止此问题,但这在长期而言,因为我们具有在插件中放置新用户控件的功能,但仍需要动态编译。因此,如果我们完全关闭动态编译,则客户将无法使用此功能。

我不希望在发生强制转换异常时不重新编译业务规则以使用新的Type,因为除了另一种解决方法之外,由于编译成本,这可能会导致性能问题。

有人知道我如何进一步调查此问题吗?我对以下更多信息特别感兴趣:IIS如何确定何时动态重新编译ascx文件以及查找更多有关此的日志记录,但是到目前为止,我还没有找到任何有用的信息。 Understanding ASP.NET Dynamic Compilation article on MSDN声明ascx / aspx / ashx / etc文件是在其第一个请求和对该文件的更改时进行编译的。但是,在部署之后,这些文件应该是静态的,尤其是在晚上甚至没有RDP访问服务器的晚上的时候。

0 个答案:

没有答案