.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(); // <<< после этой строки все системные ресурсы будут корректно освобождены
}
}