Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
@thomask
Да, Hyperterminal действительно включает fAbortOnError в DCB SetCommState, что объясняет большинство исключений IOExceptions, создаваемых объектом SerialPort. Некоторые ПК / карманные компьютеры также имеют UART, у которых по умолчанию включен флаг прерывания при ошибке, поэтому обязательно, чтобы процедура инициализации последовательного порта очищала его (что Microsoft не сделала). Недавно я написал длинную статью, чтобы объяснить это более подробно (см. this , если вам интересно).
Вы не можете закрыть кого-то elses соединение с портом, следующий код никогда не будет работать:
if (serialPort.IsOpen) serialPort.Close();
, поскольку Ваш объект не открыл порт, Вы не можете закрыть его.
Также необходимо закрыть и расположить последовательный порт даже после того, как исключения происходят
try
{
//do serial port stuff
}
finally
{
if(serialPort != null)
{
if(serialPort.IsOpen)
{
serialPort.Close();
}
serialPort.Dispose();
}
}
, Если Вы хотите, чтобы процесс был прерываем тогда, необходимо Проверить, открыт ли порт и затем обратно прочь в течение периода, и затем попробуйте еще раз, что-то как.
while(serialPort.IsOpen)
{
Thread.Sleep(200);
}
Я попытался изменить поток работы как это с тем же самым результатом. Как только HyperTerminal однажды преуспевает в том, чтобы "получить порт" (в то время как мой поток спит), мой сервис не будет в состоянии открыть порт снова.
public void DoorOpener()
{
while (true)
{
SerialPort serialPort = new SerialPort();
Thread.Sleep(1000);
serialPort.PortName = "COM1";
serialPort.BaudRate = 9600;
serialPort.DataBits = 8;
serialPort.StopBits = StopBits.One;
serialPort.Parity = Parity.None;
try
{
serialPort.Open();
}
catch
{
}
if (serialPort.IsOpen)
{
serialPort.DtrEnable = true;
Thread.Sleep(1000);
serialPort.Close();
}
serialPort.Dispose();
}
}
progressBar.setSecondaryProgress((int)value);
ProgressBarAnimation вместо progressBar.setProgress((int) value);
– Zahidul
8 May 2018 в 06:57
Вы попытались оставить порт открытым в Вашем приложении, и просто повернуть DtrEnable вкл\выкл, и затем закрыть порт, когда Ваше приложение закрывается? т.е.:
using (SerialPort serialPort = new SerialPort("COM1", 9600))
{
serialPort.Open();
while (true)
{
Thread.Sleep(1000);
serialPort.DtrEnable = true;
Thread.Sleep(1000);
serialPort.DtrEnable = false;
}
serialPort.Close();
}
я не знаком с семантикой DTR, таким образом, я не знаю, работало ли это.
Этот код, кажется, работает правильно. Я протестировал его на своей локальной машине в консольном приложении, с помощью Procomm Плюс открыться/закрыть порт, и программа продолжает отсчитывать.
using (SerialPort port = new SerialPort("COM1", 9600))
{
while (true)
{
Thread.Sleep(1000);
try
{
Console.Write("Open...");
port.Open();
port.DtrEnable = true;
Thread.Sleep(1000);
port.Close();
Console.WriteLine("Close");
}
catch
{
Console.WriteLine("Error opening serial port");
}
finally
{
if (port.IsOpen)
port.Close();
}
}
}
Я думаю, что пришел к выводу, что HyperTerminal не играет хорошо. Я запустил следующий тест:
Запускают мой сервис в "консольном режиме", он начинает переключать устройство вкл\выкл (я могу сказать, он - светодиод).
Запускают HyperTerminal и соединяются с портом. Устройство остается (HyperTerminal повышает DTR), Мой сервис пишет в журнал событий, что это не может открыть порт
Остановка HyperTerminal, я проверяю, что это правильно закрывается с помощью диспетчера задач
, устройство остается неизменным (HyperTerminal понизил DTR), мое приложение продолжает писать в журнал событий, говоря, что это не может открыть порт.
я запускаю третье приложение (тот, который я должен сосуществовать с), и скажите ему соединяться с портом. Я делаю так. Никакие ошибки здесь.
я останавливаю вышеупомянутое приложение.
ВУАЛЯ, мой сервис умирает снова, порт открывается успешно, и светодиод идет ВКЛ\ВЫКЛ.
applyTransformation()
сохранил мой день! Благодарит тонну.
– ritesht93
23 November 2016 в 05:52
Существует ли серьезное основание помешать Вашему сервису "владеть" портом? Посмотрите на встроенный сервис UPS - как только Вы говорите ему, что существует UPS, присоединенный к, скажем, COM1, можно поцеловать на прощание с тем портом. Я предложил бы, чтобы Вы сделали то же, если нет сильное операционное требование для совместного использования порта.
Этот ответ добирался до долго, чтобы быть комментарием...
я полагаю этому, когда Ваша программа находится в Потоке. Сон (1000) и Вы открываете свое Соединение HyperTerminal, HyperTerminal берет на себя управление над последовательным портом. Когда Ваша программа тогда просыпается и пытающийся открыть последовательный порт, IOException брошен.
Модернизация Ваш метод и попытка обработать открытие порта по-другому.
РЕДАКТИРОВАНИЕ: Об этом необходимо перезагрузить компьютер, когда программа перестала работать...
, Что, вероятно, потому что Ваша программа isnВґt действительно закрытый, откройте свой taskmanager и посмотрите, можно ли найти сервис программы. Обязательно остановите все Ваши потоки прежде, чем выйти из Вашего приложения.
не использует методы блокирования, внутренний класс помощника имеет некоторые тонкие ошибки.
Использование APM с классом состояния сеанса, экземпляры которого управляют буферным и буферным курсором, совместно использованным через вызовы и реализацию обратного вызова, которая переносится EndRead
в try...catch
. В нормальном функционировании последняя вещь try
, который должен сделать блок, настраивается следующий перекрытый обратный вызов ввода-вывода с вызовом к BeginRead()
.
то, Когда вещи спутываются, catch
, должно асинхронно вызвать делегата в методе перезапуска. Реализация обратного вызова должна сразу выйти после catch
блок так, чтобы логика перезапуска могла уничтожить текущую сессию (состояние сеанса почти наверняка повреждено) и создают новую сессию. Метод перезапуска должен не быть реализованным на классе состояния сеанса, потому что это препятствовало бы тому, чтобы он уничтожил и воссоздал сессию.
, Когда объект SerialPort закрывается (который произойдет, когда приложение выйдет) может быть незаконченная операция ввода-вывода. Когда это будет так, закрытие SerialPort инициирует обратный вызов, и при этих условиях EndRead
выдаст исключение, которое неотличимо от общего comms shitfit. Необходимо установить флаг в состоянии сеанса для запрещения поведения перезапуска в catch
блок. Это будет мешать Вашему методу перезапуска вмешаться в естественное завершение работы.
на Эту архитектуру можно положиться для не содержания на объект SerialPort неожиданно.
метод перезапуска справляется с закрытием и повторным открытием объекта последовательного порта. После вызова Close()
на эти SerialPort
объект звоните Thread.Sleep(5)
, чтобы дать ему шанс отпустить. Для чего-то еще возможно захватить порт, так быть готово иметь дело с этим при повторном открытии его.
interpolatedTime
является значением, переданным setDuration()
– ritesht93
23 November 2016 в 15:50