BackgroundService内存泄漏SqlDependency



这是我的服务代码

public class Worker : BackgroundService
{
public bool isRegister { get; set; }
public bool checkIp { get; set; }
public long timePass { get; set; }
public Worker()
{
}
public override Task StartAsync(CancellationToken cancellationToken)
{
return base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
if (isRegister == false)
registerSelect();
if (checkIp == true)
{
checkIp = false;
await SecurityConfig.cacheServices?.BuildServiceProvider()?.GetService<IBlockFirewallIpService>().RegisterInFirewall();
}
timePass += 1000;
if (timePass % 60000 == 0)
await SecurityConfig.cacheServices?.BuildServiceProvider()?.GetService<IBlockFirewallIpService>().RegisterInFirewall();
await Task.Delay(1000, stoppingToken);
}
}
public void registerSelect()
{
isRegister = true;
using (SqlConnection conn = new SqlConnection(GetDbConnection()))
{
conn.Open();
SqlDependency.Start(GetDbConnection());
string commandText = "SELECT [Ip1],[Ip2] ,[Ip3] ,[Ip4] FROM dbo.BlockFirewallIps where IsRead is null";
using (SqlCommand cmd = new SqlCommand(commandText, conn))
{
SqlDependency dependency = new SqlDependency(cmd);
dependency.OnChange += new OnChangeEventHandler(OnDependencyChange);
cmd.ExecuteNonQuery();
}
conn.Close();
}
}
void OnDependencyChange(object sender, SqlNotificationEventArgs e)
{
if (e.Info == SqlNotificationInfo.Insert)
checkIp = true;
SqlDependency temp = sender as SqlDependency;
if (temp != null)
temp.OnChange -= new OnChangeEventHandler(OnDependencyChange);
registerSelect();
}
private string GetDbConnection()
{
return GlobalConfig.Configuration["ConnectionStrings:DefaultConnection"];
}
}

这是我的IBlockFirewallIpService.RegisterInFirewall((代码

public async Task RegisterInFirewall()
{
var allBlockIps = await db.BlockFirewallIps.Where(t => t.IsRead == null).ToListAsync();
foreach (var ip in allBlockIps)
{
BanIP("OjeFirTCP" + ip.Ip1 + "_" + ip.Ip2 + "_" + ip.Ip3 + "_" + ip.Ip4, ip.Ip1 + "." + ip.Ip2 + "." + ip.Ip3 + "." + ip.Ip4, "Any", "TCP");
BanIP("OjeFirUDP" + ip.Ip1 + "_" + ip.Ip2 + "_" + ip.Ip3 + "_" + ip.Ip4, ip.Ip1 + "." + ip.Ip2 + "." + ip.Ip3 + "." + ip.Ip4, "Any", "UDP");
ip.IsRead = true;
db.SaveChanges();
}
}
void BanIP(string RuleName, string IPAddress, string Port, string Protocol)
{
if (OperatingSystem.IsWindows())
{
if (!string.IsNullOrEmpty(RuleName) && !string.IsNullOrEmpty(IPAddress) && !string.IsNullOrEmpty(Port) && !string.IsNullOrEmpty(Protocol) && new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
{
using (Process RunCmd = new Process())
{
RunCmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
RunCmd.StartInfo.FileName = "cmd.exe";
RunCmd.StartInfo.Arguments = "/C netsh advfirewall firewall add rule name="" + RuleName + "" dir=in action=block remoteip=" + IPAddress + " remoteport=" + Port + " protocol=" + Protocol;
RunCmd.Start();
}
}
}
}

这是progeram.cs

IHost host = Host.CreateDefaultBuilder(args)
.UseWindowsService(options =>
{
options.ServiceName = "OjeFirewall";
})
.ConfigureServices((hostContext, services) =>
{
GlobalConfig.Configuration = hostContext.Configuration;
services.AddScoped<IHttpContextAccessor, FakeIHttpContextAccessor>();
SecurityConfig.Config(services);
services.AddHostedService<Worker>();
})
.Build();

等待主持人。RunAsync((;

这是安全配置。配置代码

services.AddDbContext<SecurityDBContext>(options =>
options.UseSqlServer(GlobalConfig.Configuration["ConnectionStrings:DefaultConnection"],
b => b.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery))
, ServiceLifetime.Singleton
);
services.AddSingleton<IIpLimitationWhiteListService, IpLimitationWhiteListService>();
services.AddSingleton<IIpLimitationBlackListService, IpLimitationBlackListService>();
services.AddSingleton<IFileAccessRoleService, FileAccessRoleService>();
services.AddSingleton<IRoleService, RoleService>();
services.AddSingleton<IBlockClientConfigService, BlockClientConfigService>();
services.AddSingleton<IBlockAutoIpService, BlockAutoIpService>();
services.AddSingleton<IBlockFirewallIpService, BlockFirewallIpService>();

问题:

该代码在3天后使用了太多内存第一次调用(OnDependencyChange(后开始使用内存20mb,使用47mb3天后使用178mb

我哪里做错了?!

我发现有问题

await SecurityConfig.cacheServices?.BuildServiceProvider()?.GetService<IBlockFirewallIpService>().RegisterInFirewall();

这行代码是在将其更改为正常注入后出现的问题,现在ram的使用稳定了,但我不明白是什么!?

相关内容

  • 没有找到相关文章

最新更新