Это старый пост, но я думаю, что это решение может помочь людям с той же проблемой.
Я использовал устаревший код для приложения и обнаружил, что проблема с BeginRead и EndRead заключается в том, что невозможно отменить асинхронную операцию. Поэтому, когда вы закрываете порт, ваш вызов BeginRead остается там до тех пор, пока в порту не будет получен другой байт, тогда ваш вызов EndRead освободит порт. Если этого не происходит, приложение может зависнуть, и даже диспетчер задач не сможет его закрыть, пока вы не отключите кабель последовательного порта!
К счастью, библиотека TPL может решить эту проблему очень простым и элегантным способом. CancelToken - это то, что вам нужно:
В открытом порту:
while (x)
var myTask = _serialPort.BaseStream.ReadAsync(_serialBuffer, 0, _bufferLength, cancelToken.Token);
var bytesRead = await myTask;
... your business logic here...
if ((myTask.IsCanceled) || (myTask.IsFaulted)) break;
}
При закрытии порта:
cancelToken.Cancel(false);
Обратите внимание, что цикл while лучше рекурсивного вызова, потому что когда порт передает много информации, исключение переполнения стека выдается через 15 минут.
Это очень простая реализация. Я надеюсь, что это поможет