C# 在.Net Core 3.1中使用NetFwTypeLib时内存泄漏

C# 在.Net Core 3.1中使用NetFwTypeLib时内存泄漏,c#,.net-core,.net-core-3.1,windows-firewall-api,C#,.net Core,.net Core 3.1,Windows Firewall Api,我在一直在开发的IDS/IPS流量监视器控制台应用程序中发现了内存泄漏。我以为是实体框架,结果是防火墙代码。下面的代码在.NET4.6.2中工作得非常好,在.NETCore中工作得非常好。但是,它有内存泄漏(特别是第二行防火墙规则): 在生产环境中,它只是“按原样”执行这个方法,并且只消耗内存。同样,它是针对.NETCore的,因为我在.NET4.6.1(未注释)中运行了相同的代码一年多,没有出现任何问题 现在,我考虑了一下,并对它进行了注释,我还可以通过一些循环对它进行内部故障排除。这是一场比

我在一直在开发的IDS/IPS流量监视器控制台应用程序中发现了内存泄漏。我以为是实体框架,结果是防火墙代码。下面的代码在.NET4.6.2中工作得非常好,在.NETCore中工作得非常好。但是,它有内存泄漏(特别是第二行
防火墙规则):

在生产环境中,它只是“按原样”执行这个方法,并且只消耗内存。同样,它是针对.NETCore的,因为我在.NET4.6.1(未注释)中运行了相同的代码一年多,没有出现任何问题

现在,我考虑了一下,并对它进行了注释,我还可以通过一些循环对它进行内部故障排除。这是一场比赛

它当前运行的服务器是Windows server 2016

更新2:它也可以在Windows 10中复制。下面是复制错误的完整代码的示例:

using System;
using System.Linq;
using NetFwTypeLib;

namespace FirewallLeakTesterCore
{
    class Program
    {
        static void Main(string[] args)
        {
            int count = 0;
            while (count < 1000)
            {
                Console.WriteLine(count += 1);
                INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
                INetFwRule firewallRule = firewallPolicy.Rules.OfType<INetFwRule>().Where(x => x.Name == "firewallRuleName").FirstOrDefault();

            }
            Console.ReadKey();
        }
    }
}
使用系统;
使用System.Linq;
使用NetFwTypeLib;
命名空间FirewallLeakTesterCore
{
班级计划
{
静态void Main(字符串[]参数)
{
整数计数=0;
同时(计数<1000)
{
控制台写入线(计数+=1);
INetFwPolicy2防火墙策略=(INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID(“HNetCfg.FwPolicy2”);
INetFwRule firewallRule=firewallPolicy.Rules.OfType()。其中(x=>x.Name==“firewallRuleName”).FirstOrDefault();
}
Console.ReadKey();
}
}
}
结果如下:

Visual Studio诊断工具:

看起来像微软的bug?我想我会尝试解决其中一个内存分析器,但即使我发现了问题,我能做什么?这是对基本windows库的基本调用,我认为这就是为什么评论中的一些人没有抓住要点的原因

我没有要求任何人对我的应用程序进行内存配置或跟踪问题(从来没有……我已经这样做了)。我在寻求替代方案。是否可能有一个结构或linq问题或其他声明完全可以使用


如果你不想回答这个问题,那就这样吧,但我很难相信没有其他人会碰到这个问题。

为什么不使用内存分析器(例如or)来检查你的假设是否正确?你是在让我们猜测我们看不到的应用程序中,在我们不知道的库中,内存泄漏在哪里,PerfView是免费的、独立的,可用于分析堆内存。它值得使用,例如PerfView。不需要太多的学习(只需要几个小时)就可以获得足够的技能,从中获得一些不错的结果,这比避免学习如何使用概要文件所浪费的时间要少得多。我已将我的项目降级为.Net Framework 4.6.1。然而,对于那个些想关注这个问题的人(因为它似乎并没有在谷歌和其他有明显关键词的网站上建立索引):为什么不使用内存分析器(例如or)来检查你们的假设是否正确?你们是在问我们在一个我们看不到的应用程序中,在我们不知道TBTW的库中,内存泄漏在哪里,PerfView是免费的、独立的,可用于分析堆内存。它值得使用,例如PerfView。不需要太多的学习(只需要几个小时)就可以获得足够的技能,从中获得一些不错的结果,这比避免学习如何使用概要文件所浪费的时间要少得多。我已将我的项目降级为.Net Framework 4.6.1。然而,对于那个些想关注这个问题的人(因为它似乎并没有在谷歌和其他有明显关键字的网站上建立索引):
public static void FirewallSetup(string ip, string countryCode, bool isIpsString)
        {

        //    FirewallControl fwCtrl = new FirewallControl();
        //    fwCtrl.Block(ip, countryCode, isIpsString);
        //}

        //private void Block(string ip, string countryCode, bool isIpsString)
        //{
            var remoteAddresses = "*";
            string fwRuleName;
            bool createNewFwRule = false;

            //var fwRuleSuffix = SQLControl.GetFirewallRuleSuffix(countryCode).ToString();
            //if (string.IsNullOrEmpty(fwRuleSuffix) || fwRuleSuffix == "0")
            //{
                fwRuleName = fwRuleNamePrefix + countryCode;
            //}
            //else
            //{
            //    fwRuleName = fwRuleNamePrefix + countryCode + fwRuleSuffix;
            //}

            INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
            INetFwRule firewallRule = firewallPolicy.Rules.OfType<INetFwRule>().Where(x => x.Name == fwRuleName).FirstOrDefault();

            //if (firewallRule == null)
            //{
            //    createNewFwRule = true;
            //}
            //else
            //{
            //    //We need the following for creating the remoteAddresses string below
            //    //but, also need to count as Windows has a 5000 ip limit per rule
            //    remoteAddresses = firewallRule.RemoteAddresses;
            //    string[] aRemoteAddresses = remoteAddresses.Split(",");
            //    int remoteAddressesCount = aRemoteAddresses.Length;
            //    //Log.Debug(">>>Firewall remote addresses scope=" + remoteAddresses);
            //    Log.Warning(">>>" + fwRuleName + " Firewall remote addresses count:" + remoteAddressesCount);

            //    //5000 would be 0 to 4999 I think?
            //    if (remoteAddressesCount >= 4999)
            //    {
            //        //If remote ip scope is 5000, create a new fw rule
            //        var newFwRuleNameSuffix = SQLControl.GetNewFirewallRuleSuffix(countryCode).ToString();
            //        fwRuleName = fwRuleNamePrefix + countryCode + newFwRuleNameSuffix;

            //        createNewFwRule = true;
            //    }
            //}

            //If necessary, we create a new rule
            //TODO: Create another method for this?
            //if (createNewFwRule)
            //{
            //    firewallRule = (INetFwRule)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
            //    firewallRule.Name = fwRuleName;
            //    firewallPolicy.Rules.Add(firewallRule);
            //    firewallRule.Description = "Block inbound traffic from " + countryCode;
            //    firewallRule.Profiles = (int)NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_ALL;
            //    firewallRule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP;
            //    firewallRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN;
            //    firewallRule.Action = NET_FW_ACTION_.NET_FW_ACTION_BLOCK;
            //    firewallRule.Enabled = true;
            //    //firewallRule.RemoteAddresses = ip;
            //    //firewallPolicy.Rules.Add(firewallRule); //throws error and not needed anyway
            //    //firewallRule.LocalPorts = "4000";
            //    //firewallRule.Grouping = "@firewallapi.dll,-23255";
            //    //firewallRule.Profiles = firewallPolicy.CurrentProfileTypes;
            //}

            //if (isIpsString || remoteAddresses == "*")
            //{
            //    firewallRule.RemoteAddresses = ip;
            //}
            //else
            //{
            //    firewallRule.RemoteAddresses = remoteAddresses + "," + ip;
            //}
        }
using System;
using System.Linq;
using NetFwTypeLib;

namespace FirewallLeakTesterCore
{
    class Program
    {
        static void Main(string[] args)
        {
            int count = 0;
            while (count < 1000)
            {
                Console.WriteLine(count += 1);
                INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
                INetFwRule firewallRule = firewallPolicy.Rules.OfType<INetFwRule>().Where(x => x.Name == "firewallRuleName").FirstOrDefault();

            }
            Console.ReadKey();
        }
    }
}