4

レガシーASPコードと新しいASP.NETコードの間の互換性の理由から、いくつかの.NETユーティリティをASPに公開する.NETCOMオブジェクトがたくさんあります。場合によっては、.NETCOMラッパー内で別のCOMオブジェクトを操作する必要があります。高い柔軟性を実現し、PIAの依存関係を回避するために、動的コードを使用してこれらのCOMオブジェクトを操作することにしました。

簡略化されたC#COMオブジェクト:

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace TestCom
{
    [ComVisible(true)]
    [Guid("6DC92920-8C3C-4C81-A615-BD0E3A332024")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface ITestComObject
    {
        [DispId(1)]
        string MyMethod(dynamic dictionary);
    }

    [ComVisible(true)]
    [Guid("F52A463E-F03B-4703-860C-E86CDD6D04E3")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("TestCom.TestComObject")]
    public class TestComObject : ITestComObject
    {
        string ITestComObject.MyMethod(dynamic dictionary)
        {
            StringBuilder sb = new StringBuilder();

            if (dictionary != null)
            {
                foreach (object key in dictionary)
                {
                    object p = dictionary[key];
                    if (p != null)
                    {
                        sb.AppendFormat("{0}={1}{2}", key, p, Environment.NewLine);
                    }
                }
            }

            return sb.ToString();
        }
    }
}

ASPページのテスト:

<%@ Language=VBScript %>
<%
    Dim testObj, params
    Set testObj = Server.CreateObject("TestCom.TestComObject")

    Set params = Server.CreateObject("Scripting.Dictionary")
    params("lang") = "en-US"
    params("num") = 42

    Response.Write testObj.MyMethod(params)

    Set testObj = Nothing
    Set params = Nothing
%>

通常の場合、動的コードは1回だけコンパイルされ、後続の呼び出しで再利用されます。ただし、私たちの場合、動的コードはすべての呼び出しでコンパイルされているようです。メモリプロファイラーをIISプロセスに接続すると、gen2に表示されるMicrosoft.CSharp.RuntimeBinder.Semantics名前空間からの追加のオブジェクトをはっきりと見ることができます。これにより、IISプロセスでメモリリークが効果的に発生します。

この動的なコードコンパイルの問題を修正する方法はありますか?この場合、PIAおよびCOMインターフェースを使用するようにすべてのコードを書き直すことが常にオプションであるとは限らないことに注意してください。

4

1 に答える 1

0

メモリリークの影響を受けやすいコードを別のプロセスとして配置することをお勧めします。たとえば、親プロセスは、ソケットを介してそのようなリークのあるプロセスと通信します。次に、すべての呼び出しでこれらの漏れのあるプロセスを新たに開始するか、夕方に再起動します!

于 2012-05-31T08:23:21.367 に答える