using Oracle.ManagedDataAccess.Client; using SendNotify; using System.Data; public class RemovingBillets { private static readonly object _syncRoot = new object(); private static bool _isProcessActive = false; private static DateTime _lastCheckTime = DateTime.MinValue; public static async Task StartRemovalProcess(CancellationToken ct) { lock (_syncRoot) { if (_isProcessActive) { Log.Logger("Процесс удаления уже запущен"); return; } _isProcessActive = true; } Log.Logger("Процесс удаления: СТАРТ"); try { using (var periodicTimer = new PeriodicTimer(TimeSpan.FromSeconds(5))) { while (await periodicTimer.WaitForNextTickAsync(ct)) { if (ct.IsCancellationRequested) break; try { var result = await CheckAndSendAlerts(ct); if (!result) { Log.Logger("Нет заготовок для удаления - остановка"); break; } _lastCheckTime = DateTime.Now; } catch (Exception ex) when (ex is not OperationCanceledException) { Log.Logger($"Ошибка в процессе удаления: {ex.Message}"); } } } } catch (OperationCanceledException) { Log.Logger("Процесс удаления: ОСТАНОВЛЕН ПО ТРЕБОВАНИЮ"); } finally { lock (_syncRoot) { _isProcessActive = false; } Program.statusRemovingBillets = false; Log.Logger("Процесс удаления: ФИНАЛИЗАЦИЯ"); } } private static async Task CheckAndSendAlerts(CancellationToken ct) { const string oracleConn = "User Id=main;Password=main;Data Source=10.14.18.50:1521/izl2;"; try { using var conn = new OracleConnection(oracleConn); await conn.OpenAsync(ct); var products = await GetTrackedProducts(conn, ct); if (!products.Any()) return false; foreach (var product in products) { ct.ThrowIfCancellationRequested(); await SendToRoll(product.ProductId, conn, ct); Thread.Sleep(5000); } return true; } catch { throw; } } private static async Task> GetTrackedProducts(OracleConnection conn, CancellationToken ct) { var result = new List(); using var cmd = conn.CreateCommand(); cmd.CommandText = @" SELECT product_id, DISCHARGING_DATI FROM V_TRACKING_MILL WHERE DISCHARGING_DATI > :last_check"; cmd.Parameters.Add("last_check", OracleDbType.Date).Value = _lastCheckTime; using var reader = await cmd.ExecuteReaderAsync(ct); while (await reader.ReadAsync(ct)) { result.Add(new ProductInfo { ProductId = reader.GetInt32(0), CreatedDate = reader.GetDateTime(1) }); } return result; } private static async Task SendToRoll(int productId, OracleConnection conn, CancellationToken ct) { using var cmd = conn.CreateCommand(); cmd.CommandText = "dbms_alert.signal"; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add(new OracleParameter("name", "UI_ALERT_IZH")); cmd.Parameters.Add(new OracleParameter("message", $"send_finish_mill {productId}")); await cmd.ExecuteNonQueryAsync(ct); Log.Logger($"Отправлен сигнал удаления для ID: {productId}"); } } public class ProductInfo { public int ProductId { get; set; } public DateTime CreatedDate { get; set; } }