Закройте объект SerialPort, используя C# WPF безопасным способом - PullRequest
0 голосов
/ 02 августа 2020

Я использую штрих-код RS-232 в своей программе, и это приводит меня в новое окно. Новое окно также должно иметь возможность закрываться и снова открывать первое окно и позволять мне использовать другой штрих-код

Мой код застрял в следующей строке: barcodeManager.Dispose(); Что я делаю не так?

Я покажу важную часть моего кода: Если вам нужно больше частей моего кода, скажите мне добавить

Моя основная модель выглядит так:

Мое главное окно l oop:

public FirstWindowMV(Action close)
{
    keepLoop = true;
    this.close = close;
    TblTray_StepInSequence = null;
    tblTray = null;

    do
    {
        if(GetBarcodeData() == false)
        {
            return;
        }

        if (tblTray != null && TblTray_StepInSequence != null)
        {
            if(OpenMainWindow() == false)
            {
                return;
            }
        }
    } while (keepLoop);
}

эта часть кода: OpenMainWindow() do some logi c

Метод получения штрих-кода:

 private bool GetBarcodeData()
        {
            BarcodeSearcher barcodeSearcher = new BarcodeSearcher();
            barcodeSearcher.ShowDialog();
            BarcodeSearcherMV bmv = (BarcodeSearcherMV)barcodeSearcher.DataContext;

            if (bmv.ExitResultDialog == true)
            {
                close();
                keepLoop = false;
            } 
            TblTray_StepInSequence = bmv.TblTray_StepInSequence;
            tblTray = bmv.tblTray;
            Barcode = bmv.Barcode;

            return keepLoop;
        }

My BarcodeSearcherMV выглядит так:

public class BarcodeSearcherMV : INotifyPropertyChanged
    {
        public bool ExitResultDialog;
        public string BarcodeData { get; set; }

        private BarcodeManager barcodeManager;

        private ICommand _Exit;

        public ICommand Exit
        {
            get
            {
                if (_Exit == null)
                {
                    _Exit = new RelayCommand((param) => ExitAction());
                }
                return _Exit;
            }
        }

        private void ExitAction()
        {
            ExitResultDialog = true;
            close();
        }

        public BarcodeSearcherMV()
        {
        }

        public BarcodeSearcherMV(Action close)
        {
            this.close = close;
            barcodeManager = new BarcodeManager(barcodeAction);
        }

        private string barcode;
        private Action close;

        public string Barcode
        {
            get
            {
                return barcode;
            }
            set
            {
                barcode = value;
                barcodeAction(barcode);
            }
        }

        public tblTray_StepInSequence TblTray_StepInSequence;
        public tblTray tblTray;

        private void barcodeAction(string barcode)
        {
            TblTray_StepInSequence = DigatronSQL12ManagerInstance.GetTblTray_StepInSequences(barcode);
            tblTray = DigatronSQL12ManagerInstance.GetTblTray(barcode);
          
            if (TblTray_StepInSequence != null && tblTray  != null)
            {
                this.barcode = barcode;
                barcodeManager.Dispose();
                Application.Current.Dispatcher.Invoke(new Action(() => {
                    close();
                }));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

Мой класс BarcodeManager:

   public class BarcodeManager:IDisposable
    {
        private Action<string> barcodeAction;
        //public List<SerialPort> ScanCodeSerialPort { get; set; }
        public SerialPort ScanCodeSerialPort { get; set; }

        public BarcodeManager(Action<string> _barcodeAction)
        {
            barcodeAction = _barcodeAction;
            try
            {
                string[] ports = SerialPort.GetPortNames();

                SerialPortIniManager SerialPortIniManager = new SerialPortIniManager();
                string portName = SerialPortIniManager.GetCurrentPortName();

                try
                {
                    SerialPortIniManager spim = new SerialPortIniManager();
                    ScanCodeSerialPort = new SerialPort(portName, Convert.ToInt32(spim.GetBaudRate()),
                        (Parity)Enum.Parse(typeof(Parity), spim.GetParity()), Convert.ToInt32(spim.GetDataBits()),
                        (StopBits)Enum.Parse(typeof(StopBits), spim.GetStopBits()));
                    ScanCodeSerialPort.DataReceived += DataRecive;
                    ScanCodeSerialPort.Open();
                }
                catch (Exception ex)
                {
                    LocalPulserDBManagerInstance.WriteLog(ex.StackTrace, ex.Message);
                }
            }
            catch (Exception ex)
            {
                LocalPulserDBManagerInstance.WriteLog(ex.StackTrace, ex.Message);
                ScanCodeSerialPort = null;
            }
        }
        private void DataRecive(object serialPort, SerialDataReceivedEventArgs _event) { 
            Application.Current.Dispatcher.Invoke(new Action(() => {
            barcodeAction(((SerialPort)serialPort).ReadExisting().Trim()); 
            }));
        }
        
        public void Dispose()
        {
            
            try
            {
                if (ScanCodeSerialPort.IsOpen)
                {
                    ScanCodeSerialPort.DataReceived -= DataRecive;
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        ScanCodeSerialPort.Close();
                    });
                }
            }
            catch (Exception ex)
            {
                LocalPulserDBManagerInstance.WriteLog(ex.StackTrace, ex.Message);
                throw ex;
            }

        }
    }

Мой объект SerialPortIniManager:

public class SerialPortIniManager : IniBase
    {
        private static readonly string iniPath = @"C:\pulser\GlobalConfig.ini";
        public SerialPortIniManager() : base(iniPath)
        { }

        public string GetBaudRate()
        {
            try
            {
                return GetString("SerialPort", "BaudRate", "9600");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string GetParity()
        {
            try
            {
                return GetString("SerialPort", "Parity", "None");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string GetDataBits()
        {
            try
            {
                return GetString("SerialPort", "DataBits", "7");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string GetStopBits()
        {
            try
            {
                return GetString("SerialPort", "StopBits", "One");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public string GetCurrentPortName()
        {
            try
            {
                return GetString("SerialPort", "CurrentPortName", "COM1");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

Мой ini-файл: C: \ pulser \ GlobalConfig.ini

[SerialPort]
BaudRate = 9600
Parity = None
DataBits = 7
StopBits = One
CurrentPortName = COM1

Изображение зависания вызова в точке зависания

введите описание изображения здесь

...