我为这个问题的长度道歉,但我认为你们都会觉得值得。在我开始之前,让我说我真的在尝试制作一个独立的控制台应用程序,但遗憾的是这被证明是不可能的。该错误不会发生在控制台应用程序中。它不会发生在自包含的 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 崩溃。