2013-03-13 2 views
0

В настоящее время я работаю над приложением C#, которое требует чтения последовательного порта. В пользовательском интерфейсе есть кнопка ON/OFF, которая позволяет пользователю щелкнуть по ней, чтобы начать и прекратить чтение данных из последовательного порта. Если я постоянно нажимаю на кнопку вкл. И выкл. Это заставило исключение. Доступ к COM3 запрещен или даже сказал: «Устройство не подключено». Может ли кто-нибудь предложить лучший способ реализовать функцию последовательного порта, которая может решить ситуацию, как описано выше? Вот код, который я использую:Проблема с открытием и закрытием последовательного порта

**// Start reading data from serial port** 
public override void StartReading(string portname) 
{ 
    try 
    { 
     int k = int.Parse(portname.Replace("COM", "")); 
     if (startThread != null) 
     { 
      startThread.Abort(); 
      startThread = null; 
     } 

     startThread = new Thread(new ThreadStart(delegate 
     { 
      isActive = true; 
      try 
      { 
       using (SerialPort sp = new SerialPort(portname)) 
       { 
        if (!isActive) 
        { 
         DisposeBT(sp); 
         return; 
        } 
        sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived); 
        if (!isActive) 
        { 
         DisposeBT(sp); 
         return; 
        } 

        if (!isActive) 
        { 
         DisposeBT(sp); 
         return; 
        } 
        else 
        { 
         Thread.Sleep(6500); 
         try 
         { 
          if (sp != null && !sp.IsOpen) 
          { 
           sp.Open(); 
          } 

         } 
         catch (Exception ex) 
         { 
          Logger.Warn("Failed to open the serial port for HRM once. Try it again."); 
          Logger.Error(ex); 
          ////////////////////// new added below 
          if(sp !=null && sp.IsOpen) 
          { 
           sp.Dispose(); 
          } 
          Thread.Sleep(6500); 
          if (IsPortAvailable(k)) 
          { 
           try 
           { 
            if (sp != null && !sp.IsOpen) 
            { 
             sp.Open(); 
            } 

           } 
           catch (Exception ex1) 
           { 
            ////////////////////// new added below 
            if (sp != null && sp.IsOpen) 
            { 
             sp.Dispose(); 
            } 
            Logger.Warn("Failed to open the serial for HRM twice."); 
            Logger.Error(ex1); 
            // return; 
           } 
          } 
         } 

        } 
        while (true) 
        { 

         if (!isActive) 
         { 
          DisposeBT(sp); 
          break; 
         } 
        } 
        if (!isActive) 
        { 
         DisposeBT(sp); 
         return; 
        } 
        DisposeBT(sp); 
       } 
      } 
      catch (Exception ex) 
      { 
       Logger.Warn("Exception thrown for HRM."); 
       Logger.Error(ex); 
      } 

     })); 
     startThread.IsBackground = true; 
     startThread.Priority = ThreadPriority.Highest; 
     startThread.Start(); 
    } 
    catch (Exception ex) 
    { 
     Logger.Warn("Failed to start reading for HRM02I3A1 bluetooth device."); 
     Logger.Error(ex); 
    } 
} 

// Stop reading data from serial port 
public override void StopReading() 
{ 
    try 
    { 
     isActive = false; 
    } 
    catch { } 
} 

// event handler for the serial port to read data from sp. 
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    if (isActive)// && startThread.IsAlive 
    { 
     SerialPort sp1 = (SerialPort)sender; 
     try 
     { 
      sp1.Read(data, 0, 8); 
      decoder.Decode(data); 
     } 
     catch(Exception ex) 
     { 
      Logger.Warn("------data received from Serial Port error for HRM-------"); 
      Logger.Error(ex); 
     }; 
    } 
} 
+0

Вы не можете сделать это надежным, SerialPort требуется дополнительное время после закрытия(), прежде чем его можно будет открыть снова. Худший случай - несколько секунд. Вам нужно будет сделать это «логичным» вкл/выкл, просто выбросьте материал, который вы получите, когда он выключен. –

ответ

1

Сначала сделайте фоновый рабочий поток, принимающий событие отмены.

в методе DoWork вы можете написать что-то вроде этого

void DoWork{ 
    // init com port 
    while(no body cancelled the background worker){ 
     // if there any waiting data receive and process it. do not use event handlers 
    } 
    // close the serial port so you can open it again later. 
} 

Кроме того, если вы хотите, чтобы отменить фоновую работу было бы кусок пирога

// send cancel command. 
// wait till it is canceled. 
+0

Я написал их из памяти, извини меня за любые неправильные ключевые слова. –

+0

Спасибо, Махмуд. Сможете ли вы предоставить примерный код о том, как отменить или начать работу? –

+0

за хороший пошаговый учебник проверьте это http://www.dotnetperls.com/backgroundworker –

0

Попробуйте добавить startThread.Join() непосредственно после позвоните по номеру startThread.Abort().

Посмотрите на msdn documentation on Thread.Abort и, возможно, вы также должны проверить, что join does.

Смежные вопросы