lukevp / ESC-POS-.NET

Efficient, Easy to Use Thermal Printing & POS (Windows/Linux/OSX, WiFi/BT/USB/Ethernet)
MIT License
522 stars 171 forks source link

Buffer not getting flushed before the program exit #184

Open kedare opened 2 years ago

kedare commented 2 years ago

Hello

I have made a simple test using the sample from the README. It looks like the buffer (in my case it's a serial printer) it not flushed before the program ends.

I had to add a Thread.Sleep(2000) at the end to make sure it's flushed (nothing guaranteed here either?) Is there a way to force a flush instead of the non guaranteed wait ? Not sure if the finalizers are properly called in this case ?

Thanks

kedare commented 2 years ago

Probably related to #170 In my case it's on a NCR 7167 over serial port (serial over USB)

With the following code

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.DependencyInjection;
using System.Threading;
using ESCPOS_NET;
using ESCPOS_NET.Emitters;
using ESCPOS_NET.Utilities;

var servicesProvider = new ServiceCollection()
                .AddLogging(configure => configure.AddConsole())// use .AddLogging(configure => configure.AddConsole()) if you want see the logs on the console.
                .Configure<LoggerFilterOptions>(options => options.MinLevel = LogLevel.Debug)
                .BuildServiceProvider();

// See https://aka.ms/new-console-template for more information
Console.WriteLine("INIT");

var printer = new SerialPrinter(portName: "/dev/ttyUSB0", baudRate: 9600);

// Define a callback method.
static void StatusChanged(object sender, EventArgs ps)
{
    var status = (PrinterStatusEventArgs)ps;
    Console.WriteLine($"Status: {status.IsPrinterOnline}");
    Console.WriteLine($"Has Paper? {status.IsPaperOut}");
    Console.WriteLine($"Paper Running Low? {status.IsPaperLow}");
    Console.WriteLine($"Cash Drawer Open? {status.IsCashDrawerOpen}");
    Console.WriteLine($"Cover Open? {status.IsCoverOpen}");
}

// In your program, register event handler to call the method when printer status changes:
printer.StatusChanged += StatusChanged;

Console.WriteLine("CONNECTED");

var e = new EPSON();
printer.Write(
  ByteSplicer.Combine(
    e.CenterAlign(),
    e.PrintImage(File.ReadAllBytes("images/pd-logo-300.png"), true),
    e.PrintLine(),
    e.SetBarcodeHeightInDots(360),
    e.SetBarWidth(BarWidth.Default),
    e.SetBarLabelPosition(BarLabelPrintPosition.None),
    e.PrintBarcode(BarcodeType.ITF, "0123456789"),
    e.PrintLine(),
    e.PrintLine("B&H PHOTO & VIDEO"),
    e.PrintLine("420 NINTH AVE."),
    e.PrintLine("NEW YORK, NY 10001"),
    e.PrintLine("(212) 502-6380 - (800)947-9975"),
    e.SetStyles(PrintStyle.Underline),
    e.PrintLine("www.bhphotovideo.com"),
    e.SetStyles(PrintStyle.None),
    e.PrintLine(),
    e.LeftAlign(),
    e.PrintLine("Order: 123456789        Date: 02/01/19"),
    e.PrintLine(),
    e.PrintLine(),
    e.SetStyles(PrintStyle.FontB),
    e.PrintLine("1   TRITON LOW-NOISE IN-LINE MICROPHONE PREAMP"),
    e.PrintLine("    TRFETHEAD/FETHEAD                        89.95         89.95"),
    e.PrintLine("----------------------------------------------------------------"),
    e.RightAlign(),
    e.PrintLine("SUBTOTAL         89.95"),
    e.PrintLine("Total Order:         89.95"),
    e.PrintLine("Total Payment:         89.95"),
    e.PrintLine(),
    e.LeftAlign(),
    e.SetStyles(PrintStyle.Bold | PrintStyle.FontB),
    e.PrintLine("SOLD TO:                        SHIP TO:"),
    e.SetStyles(PrintStyle.FontB),
    e.PrintLine("  FIRSTN LASTNAME                 FIRSTN LASTNAME"),
    e.PrintLine("  123 FAKE ST.                    123 FAKE ST."),
    e.PrintLine("  DECATUR, IL 12345               DECATUR, IL 12345"),
    e.PrintLine("  (123)456-7890                   (123)456-7890"),
    e.PrintLine("  CUST: 87654321"),
    e.PrintLine(),
    e.PrintLine()
  )
);

Console.WriteLine("END");
Thread.Sleep(2000);

Remove the Thread.Sleep(2000); and nothing is printed. (Also tried to get the logs out of the library but no luck so far)

lukevp commented 2 years ago

There is not an explicit flush because this library is intended to be used in long-running processes, so there is a background thread which queues and flushes writes on a schedule. It's basically its own spooler implementation. Release 3.0.0 in #189 added support for an immediate network printer where you're allowed to await the writes, we could do something similar for serial printing. Would love a contribution if you're interested, it shouldn't be too difficult if you follow the example of the network printer.

nivle commented 1 year ago

There is not an explicit flush because this library is intended to be used in long-running processes, so there is a background thread which queues and flushes writes on a schedule. It's basically its own spooler implementation. Release 3.0.0 in #189 added support for an immediate network printer where you're allowed to await the writes, we could do something similar for serial printing. Would love a contribution if you're interested, it shouldn't be too difficult if you follow the example of the network printer.

@lukevp This would indeed be a great feature for serial printing, cus working with Thread.Sleep(2000) is just unpredictable.