.NET 4.x После закрытия приложения процесс не завершается - C#

Узнай цену своей работы

Формулировка задачи:

Сделал приложение для работы с HID устройствами. Всё что мне необходимо она выполняет, НО когда нажимаю "Подключиться" событие buttonConnect_Click и после этого закрываю приложение в диспетчере задач висит процесс и убивается только вручную через этот самый диспетчер. Вроде всё по порядку делаю, при закрытии формы использую usb.stopRead(); usb.Disconnect(); а толку ноль. Как корректно завершить программу?
using System;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using USBHIDDRIVER;
 
namespace WindowsFormsApplication_HID
{
    public partial class Form1 : Form
    {
        //Работа с USB HID
        USBHIDDRIVER.USBInterface usb;
        byte[] currentRecord = null;
 
        int InBase = 2; //Основание системы счисления для вывода в richTextBox_IN
        int OutBase = 10; //Основание системы счисления для вывода на устройство
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void buttonConnect_Click(object sender, EventArgs e)
        {
            if (usb == null)
            {
                ConnectDevice();
            }
        }
 
        void ConnectDevice()
        {
            usb = new USBInterface("vid_" + textBox_VID.Text, "pid_" + textBox_PID.Text); //Ищем USB HID устройство
            Thread.Sleep(5);
 
            if (usb.Connect()) //Если подключились
            {
                usb.enableUsbBufferEvent(new System.EventHandler(usbEventCacher)); //Событие срабатывает если с устройства пришли данные
                usb.startRead(); //Запускаем чтение с устройства
                Thread.Sleep(5);
 
                labelHIDStatus.Text = "HID устройство успешно подключено";
                labelHIDStatus.ForeColor = System.Drawing.Color.Green;
            }
            else
            {
                labelHIDStatus.Text = "HID устройство не подключено к ПК";
                labelHIDStatus.ForeColor = System.Drawing.Color.Red;
            }
        }
 
        //Вывод системного времени в статус бар
        public void GetSysTime()
        {
            while(true)
            {
                if (!toolStripStatusTime.IsDisposed)
                {
                    toolStripStatusTime.Text = DateTime.Now.ToString("hh:mm:ss:fff"); //Выводим время в статус бар
                    Thread.Sleep(100); //Задержка 100 мсек
                }
 
            }
        }
 
        //Событие вызывается когда будет принят новый набор данных
        public void usbEventCacher(object sender, System.EventArgs e)
        {
            if (USBHIDDRIVER.USBInterface.usbBuffer.Count > 0)
            {
                int counter = 0;
                while ((byte[])USBHIDDRIVER.USBInterface.usbBuffer[counter] == null)
                {
                    //Remove this report from list
                    lock (USBHIDDRIVER.USBInterface.usbBuffer.SyncRoot)
                    {
                        USBHIDDRIVER.USBInterface.usbBuffer.RemoveAt(0);
                    }
                }
                //since the remove statement at the end of the loop take the first element
                currentRecord = (byte[])USBHIDDRIVER.USBInterface.usbBuffer[0];
                lock (USBHIDDRIVER.USBInterface.usbBuffer.SyncRoot)
                {
                    USBHIDDRIVER.USBInterface.usbBuffer.RemoveAt(0);
                }
            }
 
            //Вывод получаемых данных от HID устройства в richTextBox_IN
            if (richTextBox_IN.IsHandleCreated && !richTextBox_IN.IsDisposed)
            {
                richTextBox_IN.Invoke((MethodInvoker)(() => richTextBox_IN.AppendText(DateTime.Now.ToString("hh:mm:ss:fff") + "\t" + ArrToString(currentRecord, InBase) + "\r\n")));
            }
        }
 
        //Преобразование массива byte[] в строку в формате DEC, HEX или BIN
        static string ArrToString(byte[] bytes, int toBase)
        {
            if (bytes == null || bytes.Length == 0) return "";
 
            StringBuilder sb;
            if (toBase == 2)
            {
                sb = new StringBuilder(bytes.Length * 8 + bytes.Length);
                for (int i = 0; i < bytes.Length; ++i) sb.Append(Convert.ToString(bytes[i], 2).PadLeft(8, '0')).Append("     ");
            }
            else if (toBase == 10)
            {
                sb = new StringBuilder(bytes.Length * 3 + bytes.Length);
                for (int i = 0; i < bytes.Length; ++i) sb.Append(bytes[i].ToString()).Append("     ");
            }
            else if (toBase == 16)
            {
                sb = new StringBuilder(bytes.Length * 2 + bytes.Length);
                for (int i = 0; i < bytes.Length; ++i) sb.Append(bytes[i].ToString("X2")).Append("     ");
            }
            else throw new ArgumentOutOfRangeException("toBase", "toBase must be one of the following: 2, 10, 16.");
 
            sb.Length -= 5; // Убираем пять лишних пробелов в конце строки
            return sb.ToString();
        }
 
        //Преобразование строки в формате DEC, HEX или BIN в byte[]
        static byte[] StringToArr(string bytes, int toBase)
        {
            byte[] bytesToOut = null;
            if (bytes == null || bytes.Length == 0) return bytesToOut;
 
            bytes = System.Text.RegularExpressions.Regex.Replace(bytes, @"\s+", ""); //удаление всех пробелов
 
            //Перевод из двоичного представления в byte[]
            if (toBase == 2)
            {
                if (bytes.Length % 8 == 0) //Если введено кол-во цифр кратных размеру байта
                {
                    byte tmp = 0;
                    int j = 0;
                    while (bytes.Length > 0) //В цикле переводим строку в массив байтов
                    {
                        tmp = Convert.ToByte(bytes.Substring(0, 8), 2); //Конвертируем в байт
                        Array.Resize(ref bytesToOut, j + 1); //увеличиваем массив на 1
                        bytesToOut[j] = tmp; //записиваем байт в массив
                        bytes = bytes.Remove(0, 8); //удаляем уже сконвертированные символы из строки
                        j++;
                    }
                }
                else
                {
                    MessageBox.Show("Последний байт не полный.\r\nИсправьте ошибку и попробуйте снова.");
                    bytesToOut = null;
                }
            }
            //Перевод из десятичного представления в byte[]
            else if (toBase == 10)
            {
                bytesToOut = bytes.Select(ch => (byte)(ch - '0')).ToArray();
            }
            //Перевод из шестнадцатиричного представления в byte[]
            else if (toBase == 16)
            {
                if (bytes.Length % 2 == 0)
                {
                    byte tmp = 0;
                    int j = 0;
                    while (bytes.Length > 0) //В цикле переводим строку в массив байтов
                    {
                        tmp = Convert.ToByte(bytes.Substring(0, 2), 16); //Конвертируем в байт
                        Array.Resize(ref bytesToOut, j + 1); //увеличиваем массив на 1
                        bytesToOut[j] = tmp; //записиваем байт в массив
                        bytes = bytes.Remove(0, 2); //удаляем уже сконвертированные символы из строки
                        j++;
                    }
                }
                else
                {
                    MessageBox.Show("Последний байт не полный.\r\nИсправьте ошибку и попробуйте снова.");
                    bytesToOut = null;
                }
            }
            else throw new ArgumentOutOfRangeException("toBase", "toBase must be one of the following: 2, 10, 16.");
 
            return bytesToOut;
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            Thread timeThread = new Thread(new ThreadStart(GetSysTime)); //Создаём поток
            timeThread.IsBackground = true; //Работа в фоне
            timeThread.Priority = ThreadPriority.BelowNormal; //Приоритет ниже среднего
            timeThread.Start(); //Старт потока в котором получаем время
        }
 
        //Получить список всех подключенных HID устройств
        private void richTextBoxDevices_MouseClick(object sender, MouseEventArgs e)
        {
            USBHIDDRIVER.USBInterface usbI = new USBInterface("0");
            String[] list = usbI.getDeviceList();
            richTextBoxDevices.Clear();
            
            //проверка пустого list
            if (list != null)
            {
                richTextBoxDevices.Lines = list; //вывести список устройств в richTextBoxDevices
            }
            
        }
 
        //Отправка данных на HID устройство
        private void buttonSend_Click(object sender, EventArgs e)
        {
            byte[] bytes = StringToArr (textBox_Out.Text, OutBase); //Преобразование строки в массит байт для отправки в МК
 
            if (bytes != null) //Если массив байт не пустой
            {
                usb.stopRead();
                usb.write(bytes); //Передать массив байт на HID устройство
                if(pauseToolStripMenuItem.Text == "Пауза")
                {
                    usb.startRead();
                }
            }
        }
 
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if(usb != null)
            {
                usb.stopRead();
                usb.Disconnect();
            }
        }
 
        private void radioButtonInHex_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonInHex.Checked)
            {
                InBase = 16;
            }
        }
 
        private void radioButtonInDec_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonInDec.Checked)
            {
                InBase = 10;
            }
        }
 
        private void radioButtonInBin_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonInBin.Checked)
            {
                InBase = 2;
            }
        }
 
        private void radioButtonOutDec_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonOutDec.Checked)
            {
                OutBase = 10;
            }
        }
 
        private void radioButtonOutHex_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonOutHex.Checked)
            {
                OutBase = 16;
            }
        }
 
        private void radioButtonOutBin_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonOutBin.Checked)
            {
                OutBase = 2;
            }
        }
 
        private void clearHidListToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBoxDevices.Clear();
        }
 
        private void InputListToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox_IN.Clear();
        }
 
        private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (usb.IsStartRead == false)
            {
                usb.startRead();
                pauseToolStripMenuItem.Text = "Пауза";
            }
            else if (usb.IsStartRead == true)
            {
                usb.stopRead();
                pauseToolStripMenuItem.Text = "Старт";
            }
 
        }
    }
}

Решение задачи: «.NET 4.x После закрытия приложения процесс не завершается»

textual
Листинг программы
public void Disconnect()
{
    if (this.isConnected)
    {
        this.usbdevice.disconnectDevice();
        this.usbdevice.Dispose();  // <<< после этой строки все системные ресурсы будут корректно освобождены
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4 из 5
Похожие ответы