2015-10-16 3 views
-2

У меня возникают проблемы с моей формой в C++. Форма падает из-за моего цикла while. Цикл while необходим для проверки вывода, получаемого с внешнего устройства. это фактически приложение журнала, которое непрерывно печатает данные, которые он получает от устройства, журнал в режиме реального времени. Я использую Visual Studio 2013.C++ форма зависает во время цикла

У меня есть 1 .cpp и 1 файл заголовка. Файл заголовка включает только метод для запуска формы. В .cpp-файле функция, которая выполняет получение и проверку файла, находится в событии кнопки «Подключиться». У меня также есть кнопка разъединения, которая, очевидно, отключает соединение между формой и внешним устройством. Я подключаю его через Bluetooth. Он отлично принимает результат и точно печатает, что ему нужно для печати. Единственная проблема в том, что я больше не могу нажать кнопку разъединения, потому что она зависает.

Это мой код GetBluetoothOutput:

void GetBluetoothOutput(HANDLE btSerial) 
     { 
      std::map<char, std::string> map = { 
       { 'A', "Unit is moving forward at high speed." }, 
       { 'B', "Unit is moving forward at medium speed." }, 
       { 'C', "Unit is moving forward at low speed." }, 
       { 'D', "Unit is moving backward." }, 
       { 'E', "Turn Left." }}; 

      int previous = 0; 
     while (1) 
     { 
      DWORD dwCommModemStatus; 
      BYTE Byte; 
      DWORD dwBytesTransferred; 
      int retVal; 

      SetCommMask(btSerial, EV_RXCHAR); //receive character event 
      WaitCommEvent(btSerial, &dwCommModemStatus, 0); //wait for character 

      if (dwCommModemStatus & EV_RXCHAR) 
      { 
       ReadFile(btSerial, &Byte, 1, &dwBytesTransferred, 0); //read 1 
       retVal = Byte; 
      } 

      if (previous != retVal) 
      { 
       previous = retVal; 
       char *getOutput; 
       getOutput = (char*)&retVal; 
       auto find = map.find(*getOutput); 
       if (find != map.end()) 
       { 
        std::string description = find->second; 
        m_LogDisplayBox->Items->Add(gcnew String(description.c_str())); 
       } 
       else 
       { 
        m_LogDisplayBox->Items->Add("Unknown input sent from bluetooth."); 
       } 
      } 
      else 
      { 
       m_LogDisplayBox->Items->Add("............."); 
      } 
      m_LogDisplayBox->Update(); 
     } 
    } 

Это мой код для кнопки Connect:

private: System::Void ConnectBtnEvent(System::Object^ sender, System::EventArgs^ e) 
{ 
    m_DisconnectButton->Enabled = true; 
    m_ConnectButton->Enabled = false; 

    int m_Port = m_PortComboBox->SelectedIndex; 
    int m_BaudRate = m_BaudRateComboBox->SelectedIndex; 
    int data = m_DataComboBox->SelectedIndex; 
    int parity = m_ParityComboBox->SelectedIndex; 
    int stop = m_StopComboBox->SelectedIndex; 
    int flowControl = m_FlowControlComboBox->SelectedIndex; 

    switch (m_BaudRate) 
    { 
    case 0: 
     m_BaudRate = CBR_110; 
     break; 
    case 1: 
     m_BaudRate = CBR_300; 
     break; 
    case 2: 
     m_BaudRate = CBR_600; 
     break; 
    default: 
     m_LogDisplayBox->Items->Add("No \"Baud Rate\" selected."); 
    } 

    switch (data) 
    { 
    case 0: 
     data = 7; 
     break; 
    case 1: 
     data = 8; 
     break; 
    default: 
     m_LogDisplayBox->Items->Add("No \"Data\" selected."); 
    } 

    switch (parity) 
    { 
    case 0: 
     parity = NOPARITY; 
     break; 
    case 1: 
     parity = ODDPARITY; 
     break; 
    case 2: 
     parity = EVENPARITY; 
     break; 
    case 3: 
     parity = MARKPARITY; 
     break; 
    case 4: 
     parity = SPACEPARITY; 
     break; 
    default: 
     m_LogDisplayBox->Items->Add("No \"Parity\" selected."); 

    } 

    switch (stop) 
    { 
    case 0: 
     stop = ONESTOPBIT; 
     break; 
    case 1: 
     stop = ONE5STOPBITS; 
     break; 
    case 2: 
     stop = TWOSTOPBITS; 
    default: 
     m_LogDisplayBox->Items->Add("No \"Stop\" selected."); 
    } 

    HANDLE btSerial = BluetoothInit(m_Port, m_BaudRate, data, stop, parity); 

    if (isConnected){ 
     m_LogDisplayBox->Items->Add("Connection Successful!"); 
     GetBluetoothOutput(btSerial); //This is the method which has the while-loop for continuously reading the outputs from bluetooth. 
    } 
    else{ 
     m_LogDisplayBox->Items->Add("Connection Unsuccessful"); 
     m_DisconnectButton->Enabled = false; 
     m_ConnectButton->Enabled = true; 
    } 

} 

Я прочитал, что 1 решение заключается в использовании многопоточности. Кто-нибудь может дать другие решения, чем многопоточность, потому что я не очень хорошо знаком с потоками. Заранее спасибо!

ответ

0

Похоже, что вы находитесь в бесконечном цикле - в то время как (1) никогда не выйдет из этого цикла, вам нужно сделать что-то вроде While (isConnected), а затем отключить какое-то время в цикле.

Может проверить внутри время цикла, если кнопка отключения была нажата поможет

+0

Я не могу нажать кнопку разъединения, потому что, когда я запускаю программу, она продолжает принимать входы (которые работают правильно), но замораживает всю форму. дисплей обновляется, но я не могу использовать прокрутку вниз. – rocky

+0

он замораживается, потому что while (1) означает, что он никогда не выйдет из этого цикла, поэтому, как только вы вызовете этот цикл другим кодом после запуска, ничего другого не достигнете, поэтому вам нужно будет перепроектировать, как работает этот цикл – Rob85

0

Попробуйте использовать другое условие. while (1) - бесконечный цикл.