2016-04-14 4 views
2

Я писал код для машины. Он должен говорить RS485, и я могу использовать обычную последовательную связь для него, как это предусмотрено .netAcces denied on com port C#

Однако, поскольку аппаратное обеспечение может выйти из строя, мне нужно построить тестовые процедуры. Итак, я написал процедуру, которая повторно обнаруживает доступные компоненты. Это заполняет список «allComPorts» их строковым именем, а затем nummeric updown используется для выбора COM-порта на основе его индекса списка доступных компонентов. (да, это звучит немного сложно, но по другим причинам я использовал числовое обновление для выбора).

Проблема в том, что эта функция выполняется только в первый раз. Если я снова вызову функцию, я получу доступ, если он уже открыт. Пробовал RS485Port.Close() в разных местах, но проблема затем становится сбой, если он не был открыт jet (проблема с куриным яйцом).

Мой код, чтобы открыть порт, через идет как этот

private void RS485Activate() 
    { 
      lblNoRS485Communication.Visible = false; 
     if (cmbRS485Port.Value != 0) // if 0 then there are no serial ports 
     { 
      //rs485Port is a global declared as > System.IO.Ports.SerialPort RS485Port; 
      RS485Port = new System.IO.Ports.SerialPort(allComPorts[(int)cmbRS485Port.Value - 1]); 
      if (!RS485Port.IsOpen) 
      { 
       // RS485Port.Close(); 
       // RS485Port = new System.IO.Ports.SerialPort(allComPorts[(int)cmbRS485Port.Value - 1]); 
       RS485Port.BaudRate = 9600; 
       RS485Port.Parity = System.IO.Ports.Parity.None;     
       RS485Port.StopBits = System.IO.Ports.StopBits.One;    
       RS485Port.DataBits = 8;           
       RS485Port.Handshake = System.IO.Ports.Handshake.None;   
       RS485Port.RtsEnable = true; 
       RS485Port.Open(); <== it crashes here with access denied 
      } 
     } 
     else 
     { 
      MessageBox.Show("There is no COM port detected, the program will work but it cannot control any machinery", "WARNING", MessageBoxButtons.OK, MessageBoxIcon.Warning); 
      lblNoRS485Communication.Visible = true; // another warning 
     } 
    } 
+0

вы проверили, если порт не используется другим процессом? –

+0

хорошо, он был открыт раньше, по той же самой процедуре, но для тестирования я не могу этого принять (другие вещи могли быть обработаны машиной). и так как я не могу проверить, как: 'if (RS485Port! = Null) RS485Port. close(); 'интересно, как его решить – user3800527

+0

Вызов Close() не делает порт доступным немедленно. Существует рабочий поток, который должен выйти, тот, который генерирует событие DataReceived и ErrorReceived. Как долго это происходит, непредсказуемо. Но вы, конечно же, можете сказать из исключения :) Сон на какое-то время и повторите попытку. Не пытайтесь навсегда, так как это может быть другой процесс, который уже утверждал порт. –

ответ

0

Я не люблю взгляды этого, так что я надеюсь, что есть лучший путь. Но, работая над созданием try catch, его сначала пытались закрыть (где try-catch защищает от ошибки close(), если она еще не была инициализирована. Ну, мне не нравится этот обходной путь, поэтому лучше решения приветствуются, я не думаю, что код должен предвидеть и быть основаны на ошибках. (или это нормально в эти дни с .net?)

  //...     
      try 
      { RS485Port.Close(); } 
      catch 
      { } 
      RS485Port = new System.IO.Ports.SerialPort(allComPorts[(int)cmbRS485Port.Value - 1]); 
      if (!RS485Port.IsOpen) 
      { 
       // RS485Port.Close(); 
       // RS485Port = new System.IO.Ports.SerialPort(allComPorts[(int)cmbRS485Port.Value - 1]); 
       RS485Port.BaudRate = 9600; 
       RS485Port.Parity = System.IO.Ports.Parity.None;   
       RS485Port.StopBits = System.IO.Ports.StopBits.One;  
       RS485Port.DataBits = 8;          
       RS485Port.Handshake = System.IO.Ports.Handshake.None;  
       RS485Port.RtsEnable = true; 
       RS485Port.Open(); 
      }