Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 4.0 COM互操作中动态代码的内存泄漏_C# 4.0_Dynamic_Asp Classic_Memory Leaks_Com Interop - Fatal编程技术网

C# 4.0 COM互操作中动态代码的内存泄漏

C# 4.0 COM互操作中动态代码的内存泄漏,c#-4.0,dynamic,asp-classic,memory-leaks,com-interop,C# 4.0,Dynamic,Asp Classic,Memory Leaks,Com Interop,出于旧ASP代码和新ASP.NET代码之间兼容性的原因,我们有一组.NET COM对象,它们将一些.NET实用程序公开给ASP。在某些情况下,我们需要在.NET COM包装器中使用另一个COM对象。为了实现高度灵活性并避免PIA依赖性,我们决定使用动态代码来处理这些COM对象 简化C#COM对象: using System; using System.Text; using System.Runtime.InteropServices; namespace TestCom { [Com

出于旧ASP代码和新ASP.NET代码之间兼容性的原因,我们有一组.NET COM对象,它们将一些.NET实用程序公开给ASP。在某些情况下,我们需要在.NET COM包装器中使用另一个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
%>

在正常情况下,动态代码只编译一次,后续调用将重用它。然而,在我们的例子中,似乎每次调用都会编译动态代码。当我将内存探查器连接到IIS进程时,我可以清楚地看到gen2中出现了Microsoft.CSharp.RuntimeBinder.Semantics命名空间中的其他对象。这会在IIS进程中导致内存泄漏


有没有办法解决这个动态代码编译问题?请注意,在我们的案例中,重写所有代码以使用PIA和COM接口并不总是一个选项。

我建议您将任何容易发生内存泄漏的代码作为单独的进程—例如,父进程通过套接字与此类泄漏的进程通信。然后,要么在每次通话中新启动这些泄漏过程,要么在晚上某个时候重新启动它们

诺姆:在我们使用ASP和COM互操作的情况下,您的建议实际上是无效的。此外,我认为从原则上讲,忽略内存泄漏而只是重新启动一个进程是不可接受的。