diff --git a/EpsonPrintService/EpsonPrintService.csproj b/EpsonPrintService/EpsonPrintService.csproj index 0f39dc9..92925e7 100644 --- a/EpsonPrintService/EpsonPrintService.csproj +++ b/EpsonPrintService/EpsonPrintService.csproj @@ -5,7 +5,7 @@ net8.0 enable enable - 1.0.4 + 1.0.5 diff --git a/EpsonPrintService/PrinterDiscoveryBackgroundTask.cs b/EpsonPrintService/PrinterDiscoveryBackgroundTask.cs index 3852e21..a3644e0 100644 --- a/EpsonPrintService/PrinterDiscoveryBackgroundTask.cs +++ b/EpsonPrintService/PrinterDiscoveryBackgroundTask.cs @@ -67,10 +67,11 @@ public class PrinterDiscoveryBackgroundTask private async Task DiscoverAndNotifyAsync() { + _printServer.EnterDiscoveryLock(); try { var printers = await _discoveryService.DiscoverPrintersAsync(_discoveryTimeout); - + var currentIps = printers.Select(p => p.IPAddress).ToHashSet(); foreach (string currentIp in currentIps) @@ -90,6 +91,10 @@ public class PrinterDiscoveryBackgroundTask { _logger.LogWarning(ex, "Failed to discover printers"); } + finally + { + _printServer.ExitDiscoveryLock(); + } } private bool HasConfigurationChanged(HashSet currentIps) diff --git a/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs b/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs index a6b9be3..7151295 100644 --- a/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs +++ b/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs @@ -1,5 +1,6 @@ using Inspectron.Epson.PrintServer.Printers.Utils; using Inspectron.Epson.PrintServer.PrintServices; +using System.Reflection; namespace Inspectron.Epson.PrintServer.Printers; @@ -37,6 +38,8 @@ public class TM_U220IITranslated : IPrinter { if (command.IsCut) { + await _printer.FeedLinesAsync(10); + await Task.Delay(200 * 5); await _printer.CutAsync(false); await Task.Delay(200); continue; diff --git a/Inspectron.Epson/Queue/PrintServer.cs b/Inspectron.Epson/Queue/PrintServer.cs index 6fdc56e..7fa3137 100644 --- a/Inspectron.Epson/Queue/PrintServer.cs +++ b/Inspectron.Epson/Queue/PrintServer.cs @@ -6,18 +6,40 @@ public class PrintServer private readonly IPrintService _printService; private readonly ILogger _logger; private readonly ConcurrentDictionary _printerQueues; + private readonly ReaderWriterLockSlim _printDiscoveryLock = new(); public PrintServer(IPrintService printService, ILogger logger) { _printService = printService; _logger = logger; _printerQueues = new ConcurrentDictionary(); - + } + /// + /// Acquires a read lock for print operations. Multiple print operations can run concurrently. + /// + public void EnterPrintLock() => _printDiscoveryLock.EnterReadLock(); + + /// + /// Releases the read lock after a print operation completes. + /// + public void ExitPrintLock() => _printDiscoveryLock.ExitReadLock(); + + /// + /// Acquires a write lock for discovery operations. This blocks until all print operations complete + /// and prevents new print operations from starting. + /// + public void EnterDiscoveryLock() => _printDiscoveryLock.EnterWriteLock(); + + /// + /// Releases the write lock after discovery completes. + /// + public void ExitDiscoveryLock() => _printDiscoveryLock.ExitWriteLock(); + public void RegisterPrinter(string printerIp) { - var queue = new PrinterQueue(printerIp, _printService, _logger); + var queue = new PrinterQueue(printerIp, _printService, _logger, this); if (_printerQueues.TryAdd(printerIp, queue)) { queue.Start(); diff --git a/Inspectron.Epson/Queue/PrinterQueue.cs b/Inspectron.Epson/Queue/PrinterQueue.cs index 24f8410..fbe2da5 100644 --- a/Inspectron.Epson/Queue/PrinterQueue.cs +++ b/Inspectron.Epson/Queue/PrinterQueue.cs @@ -15,11 +15,12 @@ public class PrinterQueue private Task _processingTask; private readonly IPrintService _printService; private readonly ILogger _logger; + private readonly PrintServer _printServer; public bool IsProcessing { get; private set; } public int QueueLength => _queue.Count + _priorityQueue.Count; - public PrinterQueue(string printerIp, IPrintService printService, ILogger logger) + public PrinterQueue(string printerIp, IPrintService printService, ILogger logger, PrintServer printServer) { PrinterIp = printerIp; _queue = new ConcurrentQueue(); @@ -28,6 +29,7 @@ public class PrinterQueue _cancellationTokenSource = new CancellationTokenSource(); _printService = printService; _logger = logger; + _printServer = printServer; } public void Enqueue(PrintJob job) @@ -70,6 +72,7 @@ public class PrinterQueue { _logger.LogInformation("Processing job on printer {PrinterId}", PrinterIp); + _printServer.EnterPrintLock(); try { // Call the actual print function @@ -100,6 +103,10 @@ public class PrinterQueue _logger.LogError(ex, "Error processing job"); // Handle exception (retry, log, etc.) } + finally + { + _printServer.ExitPrintLock(); + } } } catch (OperationCanceledException)