VB.NET 2005, последовательный порт, проблема с удалением, Windows CE

Я пишу программу для Windows CE, которая должна работать с последовательными портами. Я использую объект System.IO.Ports.SerialPort. Все работает хорошо, но когда я закрываю программу и снова открываю ее, я получаю ошибку: Порт занят! В конце пишу:

port.close()
port.dispose()

И если я добавлю это:

System.GC.collect() 

.. чем все начинает работать

Но проблема в том, что компьютер зависает, когда для каждого порта вызывается сборщик мусора. Если я попытался использовать сборщик где-то еще, он не «собирает» порты, и они выглядят как использованные, если программа снова запускается.

Может кто-нибудь помочь, пожалуйста?


person Racky    schedule 12.04.2011    source источник
comment
Очень поздний комментарий, но вы можете попробовать с using (SerialPort p = new SerialPort()). Это автоматически закроет и удалит объект.   -  person i486    schedule 23.02.2015


Ответы (3)


Возможно, объект, которому принадлежит объект порта, не удален или все еще поддерживает ссылку. Это объясняет, почему после system.gc.collect() это работает.

person MarcelDevG    schedule 12.04.2011
comment
Это я поняла. Но почему сборщик не работает, когда я использую его как последнюю команду своей программы? Моя программа содержит в себе модуль и Sub Main(). В конце запускаю сборщик, но порты все равно открыты :( - person Racky; 12.04.2011
comment
Возможно, я нашел решение. VB, вероятно, не работает с объектами, как я ожидал бы в ООП. Поэтому я вручную уничтожаю все порты в конце метода Main(). Но по мере того, как я все больше и больше разбираюсь в VB.net и Visual Studio, он мне нравится все меньше и меньше :( ... например, абстрактные формы - хорошая история :) - person Racky; 12.04.2011
comment
VB, вероятно, не работает с объектами, как я ожидал в ООП. Я не думаю, что это VB, а .net framework. А также Windows CE добавляет еще один слой. - person MarcelDevG; 13.04.2011
comment
В конце я запускаю сборщик, но порты все еще открыты. Ответ ctacke может быть более правильным, чем dispose, хотя оба вопроса могут иметь значение. - person MarcelDevG; 13.04.2011

Здесь есть несколько потенциальных возможностей. Во-первых, только потому, что вы вызываете Close, это не означает, что порт физически освобожден - это верно даже для C. Это зависит от состояния UART и во многом от того, как был написан фактический драйвер. От вызова Close до фактического освобождения порта драйвером может пройти некоторое время. Я считаю, что это то, что вы на самом деле видите, потому что вы на самом деле вручную вызываете close, а не ждете, пока Finalizer уничтожит ваш экземпляр порта и неявно закроет его - это займет еще больше времени.

Конечно, это предполагает, что ваш вызов Close действительно выполняется. Если это не так, вам нужно понять, как работает Finalization объекта в управляемом коде. Это не имеет ничего общего с ООП, это связано с управлением памятью. Когда объект выходит за рамки и у него больше нет корней (ссылок), он доступен для сбора, но это не означает, что он немедленно освобождается. На самом деле до запуска финализатора может пройти довольно много времени, особенно если приложение продолжает работать.

person ctacke    schedule 12.04.2011

Как долго вы ждете между закрытием и открытием? Согласно MSDN:

Лучшей практикой для любого приложения является ожидание в течение некоторого времени после вызова метода Close, прежде чем пытаться вызвать метод Open, так как порт не может быть закрыт мгновенно.

person Chris Haas    schedule 12.04.2011
comment
Привет. Задержки по времени не имели значения. В программе я могу вызвать port.open() port.close() port.dispose() system.GC.collect() - person Racky; 13.04.2011
comment
Привет. Задержки по времени не имели значения. В программе я могу вызвать port.open() port.close() port.dispose() system.GC.collect() в строке, и это работает. Проблема в том, что программа не может вызвать деструктор этого порта, где я использую dispose() и collect(). Это проблема. Я думаю, это может быть связано с тем, что в моей программе нет основного класса, но есть основной модуль. Поэтому я вызываю деструктор вручную в конце модуля, и теперь он работает. - person Racky; 13.04.2011