0

I am having trouble with SerialPort.DataReceived event being blocked by ShowDialog from MainWindow. Originally, the code worked as follows:

Printer connected to COM port using Windows Print Driver for operation. To check status, I must "move" windows printer COM port to COM1, and connect directly to the printer via SerialPort and send it a certain array of bytes. The printer will answer back >>LOW STOCK<< if out of paper or >>READY<< if status OK. I receive this through the serialport.datareceived event that I set up when switching the com port. If I get >>LOW STOCK<<, I continue to poll the printer over the serial port every 2 seconds.

public class PrintController
{
    private PrintMonitor DefaultPrintMonitor;

    public Printcontroller()
    {
        Initialize();
    }

    private void Initialize()
    {
        // Some code here to determine which printer type to load monitor for
        DefaultPrintMonitor = new PrintMonitor();
    }

}

And the Print Monitor:

public class PrintMonitor
{
    private SerialPort Port;
    private TimeoutManager TimeoutQueue = new TimeoutQueue();
    private readonly char[] PrinterStatusCommand = new char[7] { ... The printers report status command ...};
    
    public PrintMonitor() {}

    public void StartPrintMonitor()
    {
        Thread thread = new Thread(new ThreadStart(RefreshPrintQueue))
        {
            IsBackground = true
        };
        thread.Start();
    }

    private void RefreshPrintQueue()
    {
        // This checks the Printer's Queue for any jobs remaining
        // If the number of jobs = 0, all data has been transferred to the printer
        // and we can switch the COM port so the printer can be polled for it's status
        // Code omitted for brevity
        if (jobs.Count() > 0)
        {
            // This will wait 1000ms and execute the method RefreshPrintQueue
            TimeoutQueue.AddTimeout(RefreshPrintQueue, 1000);
        }
        else
        {
            TimeoutQueue.AddTimeout(GetStatus, 500);
        }
    }

    private void GetStatus()
    {
        // Connect windows print driver to COM1
        SetWindowsPrintDriver("COM1");
        // Connect to printer using new SerialPort
        ConnectSerialPrintDriver();
        // Poll the printer over new SerialPort connection
        QueryPrinterStatus();
    }

    private void ConnectSerialPrintDriver()
    {
        //Create new serial port to Port, and open
        Port.DataReceived += Port_DataReceived;
    }

    private void QueryPrinterStatus()
    {
        byte[] send = Encoding.ASCII.GetBytes(PrinterStatusCommand);
        Port.Write(send, 0, send.Length);
        TimeoutQueue.AddTimeout(QueryPrinterStatus, 2000);
    }

    private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        Thread.Sleep(100);
        SerialPort p = sender as SerialPort;
        string recv = p.ReadExisting().Trim();
        if (recv.Contains(">>READY<<"))
        {
            // Stop Polling loop
            TimeoutQueue.ClearAllTimeouts();
            DisconnectSerialPrintDriver();
            // Raises event to Main to close ShowDialog
        }
        else
        {
            // Raises event to Main to open ShowDialog
        }
    }

    private void DisconnectSerialPrintDriver()
    {
        // Closes/Disconnects serial port from printer
        // unsubscribes event listener
        // Sets Port to null and connects windows print driver back to printers COM port
        // Ready to accept print jobs again
    }

Believe it or not, this works very well. When the paper is reloaded in the printer, the dialog window showing the paper out message is dismissed.

However, I recently had to make a change to the print controller to make it a static class. Now, when I open the dialog window at Main, the Port_DataReceived event stops firing. The polling of the printer continues, and the responses just seem to back up until the dialog window is manually dismissed, and then I get one more dataReceived event with the results of all the polling that went on while showing the dialog window.

Can anyone tell me what could be happening here?

Frandelsan
  • 21
  • 4
  • According to [ShowDialog](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.form.showdialog?view=windowsdesktop-7.0): _When this method is called, the code following it is not executed until after the dialog box is closed._ – Tu deschizi eu inchid Feb 18 '23 at 06:20
  • Use `Show` instead. – Tu deschizi eu inchid Feb 18 '23 at 06:24
  • https://stackoverflow.com/questions/75168439/how-to-add-a-yes-no-confirmation-dialog-in-a-wpf-mvvm-application/75177313#75177313 : You can use different technique for the ShowDialog – Gilad Waisel Feb 19 '23 at 16:57

0 Answers0