4

この質問の長さをお詫び申し上げますが、皆さんはそれだけの価値があると思います。始める前に、私は本当に独立したコンソール アプリケーションを作成しようとしていましたが、残念ながらそれは不可能であることがわかりました。このバグは、コンソール アプリでは発生しません。自己完結型の ASP.NET アプリでは発生しません。これは、Windows 7 の IIS 7.5 内で実行した場合にのみ発生します。

__TransparentProxyこのエラーは、 (WCF 経由の)dynamic変数と (int 型の) 変数の組み合わせが関係しているため、動的言語ランタイムに関連しているようです。問題を生成する行は、プロキシと動的 int の両方を渡す静的メソッド (たまたまメソッド本体を含まない) の呼び出しです。

メソッドが呼び出されると、w3wp.exe プロセスが CPU 全体を占有し、メモリを非常に急速に増加させ始めます (私にとっては 1 秒あたり約 100 メガバイトですが、おそらく GC のために徐々に減少します)。

このエラーを再現するには、Visual Studio で新しい ASP.NET Web サイトを作成します ("New" | "Project" "C#" | "Web" | "ASP.NET Web Application")。次に、新しいプロジェクトをホーム ディレクトリとする新しいサイトを 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 トークン) + 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> 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(オブジェクトの送信者 = {System.Web.HttpApplicationFactory}、System.EventArgs e = {システム.EventArgs}) 19 行目 + 0x1b8 バイト C#

記録のために、私は 3 台の異なるマシンで試しましたが、Windows7/IIS7.5 ボックスでのみ再現できました。Windows Server 2008 / IIS7 ボックスでは問題はありませんでした。

問題は、この問題を解決してメソッドを正常に呼び出すにはどうすればよいかということです。また、なぜこれが起こっているのですか?IIS がクラッシュするため、DLR を使用するものを呼び出すことに過度に注意する必要はありません。

4

1 に答える 1

6

なぜこれが発生するのか答えることができませんが、パラメータを渡すときにdynamicオブジェクトをキャストすることはできます。int

DontBlowUpTheProgram(fooServices, (int)dynamicId); 

おそらく、内部の知識が豊富な人は、より完全な説明で手を差し伸べるでしょう。

于 2012-04-20T16:22:31.290 に答える