Ошибка в динамическом языке во время выполнения в сочетании с IIS 7.5

Я прошу прощения за этот вопрос, но я думаю, что вы все найдете это стоит. Прежде чем я начну, позвольте мне сказать, что я действительно пытался создать изолированное консольное приложение, но, к сожалению, это оказалось невозможным. Ошибка не возникает в консольном приложении. Это не происходит в автономном приложении ASP.NET. Это происходит только при запуске в IIS 7.5 в Windows 7.

Кажется, ошибка связана с динамической средой исполнения языка, поскольку включает в себя комбинацию __TransparentProxy (через WCF) и dynamic переменная (целое число). Строка, вызывающая проблему, - это вызов статического метода (который, как оказалось, не содержит тела метода), передающего как прокси, так и динамический int.

Как только метод вызван, процесс w3wp.exe занимает весь ЦП и начинает очень быстро увеличивать объем памяти (для меня около 100 мегабайт в секунду, хотя он, вероятно, уменьшается из-за GC'ing).

Чтобы воспроизвести эту ошибку, создайте новый веб-сайт ASP.NET в Visual Studio ("Новый" | "Проект", "C#" | "Веб" | "Веб-приложение ASP.NET"). Затем создайте новый сайт в 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;

Повторите попытку, и вы снова заметите, что проблема исчезла и в этом сценарии.

Наконец, если я присоединяю отладчик и ломаю все, я могу видеть, что он делает, застряв в этом вызове метода. Кажется, всегда показывают что-то вроде:

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, цель объекта) + 0x29 байт.
System.Core.dll!System.Linq.Expressions.Expression>.Compile() + 0xbb байт
System.Core.dll!System.Runtime.CompilerServices.CallSiteBinder.BindCore>(System.Runtime.CompilerServices.CallSite> сайт, объект [] args) + 0x10a байт
System.Core.dll!System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3(System.Runtime.CompilerServices.CallSite site = {System.Runtime.CompilerServices.CallSite>}, WebApplication1.Global arg0 = {ASP.global_asax}, WebApplication arg1 = {System.Runtime.Remoting.Proxies.__TransparentProxy}, объект arg2 = 5) + 0x3f0 байт
WebApplication1.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.

1 ответ

Решение

Я не могу ответить, почему это происходит, однако dynamic Возражать int при передаче параметр будет работать.

DontBlowUpTheProgram(fooServices, (int)dynamicId); 

Возможно, кто-то с большим знанием внутренних органов придет с более полным объяснением.

Другие вопросы по тегам