4

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

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

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

要重现此错误,请在 Visual Studio 中创建一个新的 ASP.NET 网站(“新建”|“项目”“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 方法) + 0x2f 字节
mscorlib.dll!System.Reflection.Emit.DynamicResolver.ParentToken(int token) + 0x1f3 字节
[本机到托管转换]
[托管到本机转换]
mscorlib.dll!System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type delegateType, object target) + 0x29 字节
System.Core.dll!System.Linq.Expressions.Expression>.Compile() + 0xbb 字节
System.Core。 dll!System.Runtime.CompilerServices.CallSiteBinder.BindCore>(System.Runtime.CompilerServices.CallSite> site, object[] args) + 0x10a 字节
System.Core.dll!System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3(System.Runtime.CompilerServices.CallSite 站点 = {System.Runtime.CompilerServices.CallSite>},WebApplication1.Global arg0 = {ASP.global_asax},WebApplication1.Global.IFooServices arg1 = {System.Runtime.Remoting.Proxies.__TransparentProxy},对象 arg2 = 5) + 0x3f0 字节
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 崩溃。

4

1 回答 1

6

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

DontBlowUpTheProgram(fooServices, (int)dynamicId); 

也许对内部知识更了解的人会介入并进行更全面的解释。

于 2012-04-20T16:22:31.290 回答