与IIS 7.5结合使用的动态语言运行库中的错误

Kir*_*oll 4 c# dynamic-language-runtime dynamic iis-7.5 transparentproxy

我为这个问题长度道歉,但我认为你们都觉得值得.在开始之前,让我说我真的想要生成一个独立的控制台应用程序,但遗憾的是,事实证明这是不可能的.该错误不会发生在控制台应用程序中.它不会发生在一个独立的ASP.NET应用程序中.它仅在Windows 7上的IIS 7.5中运行时发生.

该错误似乎与动态语言运行时有关,因为它涉及__TransparentProxy(通过WCF)和dynamic变量(int)的组合.产生问题的那一行是调用一个传递代理和动态int的静态方法(碰巧不包含方法体).

一旦调用该方法,w3wp.exe进程占用整个CPU并开始非常快速地增加内存(对我来说,每秒大约100兆,尽管它可能因为GC而逐渐减少).

若要重现此错误,请在Visual Studio中创建一个新的ASP.NET网站("新建"|"项目""C#"|"Web"|"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)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

现在通过http://localhost:7080(或您选择的任何端口)访问浏览器中的站点.让任务管理器准备就绪,因为您需要在确认报告的症状后终止w3wp.exe进程.

要确认代理和动态是否正在共同解决此错误,请更改此行:

dynamic dynamicId = 5;
Run Code Online (Sandbox Code Playgroud)

至:

int dynamicId = 5;
Run Code Online (Sandbox Code Playgroud)

重试,你会发现问题已经消失,页面加载.现在将其更改回dynamic然后更改此行:

IFooServices fooServices = ((ChannelFactory<IFooServices>)factory).CreateChannel();
Run Code Online (Sandbox Code Playgroud)

至:

IFooServices fooServices = null;
Run Code Online (Sandbox Code Playgroud)

重试,你会再次注意到问题在这种情况下也消失了.

最后,如果我附加调试器并中断所有内容,我可以看到它在执行此方法调用时正在执行的操作.它似乎总是显示如下:

mscorlib.dll!System.RuntimeMethodHandle.GetDeclaringType(System.IRuntimeMethodInfo方法)+ 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> .Compile()+ 0xbb bytes
System.Core. dll!System.Runtime.CompilerServices.CallSiteBinder.BindCore>(System.Runtime.CompilerServices.CallSite> site,object [] args)+ 0x10a bytes
System.Core.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字节
WebApplication1.dll!WebApplication1.Global.Application_Start(o bject sender = {System.Web.HttpApplicationFactory},System.EventArgs e = {System.EventArgs})第19行+ 0x1b8字节C#

为了记录,我在三台不同的机器上尝试过它,并且只能在Windows7/IIS7.5盒子上进行重新调制.在Windows Server 2008/IIS7上没有问题.

问题是,如何解决此问题并成功调用该方法?另外,为什么会发生这种情况?我不想过于谨慎地调用将使用DLR的东西,因为它会使IIS崩溃.

Jam*_*xon 6

我无法回答为什么会发生这种情况,但是在传递参数时将dynamic对象转换为int可行.

DontBlowUpTheProgram(fooServices, (int)dynamicId); 
Run Code Online (Sandbox Code Playgroud)

也许对内部人员有更多了解的人会更全面地探索.

  • 我的确回答了这个问题.它是如何解决它的,而不是为什么它不起作用.自从它首次发布以来它发生了一些变化,但在这里我没有回答原因. (2认同)