this is my service code
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"];
}
}
and this is my IBlockFirewallIpService.RegisterInFirewall() code
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();
}
}
}
}
this is 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();
await host.RunAsync();
this is SecurityConfig.Config codes
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>();
the problem :
this code using too much memory after 3 day starting ram usage is 20mb after first call (OnDependencyChange) it use 47mb after 3 day it use 178mb
where i am doing wrong ?!
i found problem
await SecurityConfig.cacheServices?.BuildServiceProvider()?.GetService<IBlockFirewallIpService>().RegisterInFirewall();
this line code was the problem after change it to normal injection ram usage is stable now, but i can not understand whay !?