Я нашел способ, но он немного хакерский. Этот метод закрывает порт и прерывает работу, но выдает пару исключений в процессе. В основном я использую отражение, чтобы получить дескриптор файла устройства следующим образом:
object p = _port.BaseStream.GetType().GetField("_handle", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField).GetValue(_port.BaseStream);
IntPtr hFile = (IntPtr)p.GetType().GetField("handle", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField).GetValue(p);
Где _port - открытый SerialPort. Затем я закрываю файл следующим образом
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool CloseHandle(IntPtr hFile);
CloseHandle(hFile);
Возможно, есть лучший способ, вызвав один из закрытых методов в BaseStream, но это один из способов:)