与 IIS 7.5 结合使用的动态语言运行时中的错误
本文关键字:动态 语言 错误 运行时 IIS 结合 | 更新日期: 2023-09-27 18:31:44
对于这个问题的长度,我深表歉意,但我想你们都会觉得值得的。 在开始之前,让我说我真的在尝试开发一个孤立的控制台应用程序,但遗憾的是,这被证明是不可能的。 该 bug 不会在控制台应用中发生。 它不会在独立的 ASP.NET 应用中发生。 它仅在Windows 7上的IIS 7.5中运行时发生。
该错误似乎与动态语言运行时有关,因为它涉及__TransparentProxy
(通过 WCF)和dynamic
变量(int)的组合。 产生问题的行是对静态方法(恰好不包含方法主体)的调用,该方法同时传入代理和动态 int。
调用该方法后,w3wp.exe 进程会占用整个 CPU,并开始非常快速地增加内存(对我来说每秒大约 100 megs,尽管它可能是由于 GC'ing 而逐渐减少)。
若要重现此错误,请在 Visual Studio 中创建新的 ASP.NET 网站("新建" |"项目"C#" |"网络" |"ASP.NET Web 应用程序")。 然后在 IIS 中创建一个新站点,其主目录是您的新项目。(此外,向"所有人"授予对该文件夹的完全读/写访问权限,并确保应用池使用的是 .NET 4.0) 为新站点指定特定端口,例如 7080。 最后,将此代码粘贴到 Global.asax.cs:
public class Global : System.Web.HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
dynamic dynamicId = 5;
var serviceUrl = "http://localhost:7182/FooServices.svc";
ChannelFactory factory = new ChannelFactory<IFooServices>(new WSHttpBinding(), new EndpointAddress(serviceUrl));
factory.Open();
IFooServices fooServices = ((ChannelFactory<IFooServices>)factory).CreateChannel();
BlowUpTheProgram(fooServices, dynamicId); // This line hangs
}
[ServiceContract]
public interface IFooServices
{
[OperationContract]
void Bar();
}
public static void BlowUpTheProgram(IFooServices eventServices, int authorMailboxId)
{
}
}
现在通过http://localhost:7080
(或您选择的任何端口)在浏览器中访问该站点。 准备好任务管理器,因为您需要在确认报告的症状后终止 w3wp.exe 进程。
若要确认代理和动态正在协同工作以显示此错误,请更改以下行:
dynamic dynamicId = 5;
自:
int dynamicId = 5;
重试,您会注意到问题已消失并且页面加载。 现在将其改回dynamic
,然后更改此行:
IFooServices fooServices = ((ChannelFactory<IFooServices>)factory).CreateChannel();
自:
IFooServices fooServices = null;
重试,您将再次注意到问题在这种情况下也消失了。
最后,如果我附加调试器并中断所有调试器,我可以看到它在卡在此方法调用中时正在做什么。 它似乎总是显示类似以下内容:
姆科利布.dll!System.RuntimeMethodHandle.GetDeclaringType(System.IRuntimeMethodInfo method) + 0x2f 字节
姆科利布.dll!System.Reflection.Emit.DynamicResolver.ParentToken(int token) + 0x1f3 字节
[原生到托管过渡]
[设法过渡到本机]
姆科利布.dll!System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type delegateType, object target) + 0x29 字节
系统核心.dll!System.Linq.Expressions.Expression>.编译() + 0xbb 字节
系统核心.dll!System.Runtime.CompilerServices.CallSiteBinder.BindCore>(System.Runtime.CompilerServices.CallSite> site, object[] args) + 0x10a 字节
系统核心.dll!System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3(System.Runtime.CompilerServices.CallSite site = {System.Runtime.CompilerServices.CallSite>}, WebApplication1.Global arg0 = {ASP.global_asax}, WebApplication1.Global.IFooServices arg1 = {System.Runtime.Remoting.Proxies.__TransparentProxy}, object arg2 = 5) + 0x3f0 字节
网络应用程序1.dll!WebApplication1.Global.Application_Start(对象发送器 = {System.Web.HttpApplicationFactory}, System.EventArgs e = {System.EventArgs}) 第 19 行 + 0x1b8 字节 C#
作为记录,我已经在三台不同的机器上尝试过它,并且只能在Windows7/IIS7.5机器上重现。 在Windows Server 2008/IIS7盒子上没有问题。
问题是,如何解决此问题并成功调用该方法? 另外,为什么会这样? 我不想在调用将使用 DLR 的东西时过于小心,因为它会使 IIS 崩溃。
我无法回答为什么会发生这种情况,但是在传递参数时将dynamic
对象转换为int
将起作用。
DontBlowUpTheProgram(fooServices, (int)dynamicId);
也许对内部结构有更多了解的人会更全面地解释。