我为这个问题长度道歉,但我认为你们都觉得值得。在开始之前,让我说我真的试图生成一个孤立的控制台应用程序,但遗憾的是,事实证明这是不可能的。该错误不会发生在控制台应用程序中。它不会发生在一个独立的ASP.NET应用程序中。它仅在Windows 7上的IIS 7.5中运行时才会发生。
错误似乎与动态语言运行时有关,因为它涉及__TransparentProxy
(通过WCF)和dynamic
变量(int)的组合。产生问题的那一行是调用静态方法(碰巧不包含方法体),同时传递代理和动态int。
调用该方法后,w3wp.exe进程会占用整个CPU并开始非常快速地增加内存(对我来说,每秒大约100兆,尽管它可能会因为GC而逐渐减少)。
要重现此错误,请在Visual Studio中创建一个新的ASP.NET网站(" New" |" Project"" C#" |" Web" |" ASP.NET Web应用程序")。然后在IIS中创建一个新站点,其主目录是您的新项目。 (另外,给予" Everyone"对该文件夹的完全读/写访问权限并确保应用程序池使用.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;
重试,您再次注意到此问题在此方案中也已消失。
最后,如果我附加调试器并中断所有内容,我可以看到它在执行此方法调用时所执行的操作。它似乎总是显示如下:
mscorlib.dll!System.RuntimeMethodHandle.GetDeclaringType(System.IRuntimeMethodInfo method)+ 0x2f bytes
mscorlib.dll!System.Reflection.Emit.DynamicResolver.ParentToken(int token)+ 0x1f3 bytes
[原产于管理过渡]
[管理到原生过渡]
mscorlib.dll!System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type delegateType,object target)+ 0x29 bytes
System.Core.dll!System.Linq.Expressions.Expression&gt; .Compile()+ 0xbb bytes
System.Core.dll!System.Runtime.CompilerServices.CallSiteBinder.BindCore&gt;(System.Runtime.CompilerServices.CallSite&gt; site,object [] args)+ 0x10a bytes
System.Core.dll!System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3(System.Runtime.CompilerServices.CallSite site = {System.Runtime.CompilerServices.CallSite&gt;},WebApplication1.Global arg0 = {ASP.global_asax},WebApplication1.Global.IFooServices arg1 = {System.Runtime.Remoting.Proxies .__ TransparentProxy},object arg2 = 5)+ 0x3f0 bytes
WebApplication1.dll!WebApplication1.Global.Application_Start(object sender = {System.Web.HttpApplicationFactory},System.EventArgs e = {System.EventArgs})第19行+ 0x1b8字节C#
为了记录,我已经在三台不同的机器上尝试了它,并且只能在Windows7 / IIS7.5盒子上进行复制。在Windows Server 2008 / IIS7上没有问题。
问题是,如何解决此问题并成功调用该方法?另外,为什么会发生这种情况?我不想过于谨慎地调用将使用DLR的东西,因为它会使IIS崩溃。
答案 0 :(得分:6)
我无法回答为什么会发生这种情况,但是在传递参数时将dynamic
对象投射到int
将会有效。
DontBlowUpTheProgram(fooServices, (int)dynamicId);
也许对内部人士有更多了解的人会更全面地探索。