На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
  
> Событие прием данных в отдельный поток
    Вот такое событие есть в имеющемся у меня компоненте:
    void __fastcall TForm1::CommPortReceiveData(TObject *Sender, Pointer DataPtr, DWORD DataSize)

    Как его присоединить к потоку:
    void __fastcall ReceiveData::Execute()
    {
    }

    Понятно что нужно создать экземпляр класса, а дальше как?
      Цитата misyachniy @
      Вот такое событие есть в имеющемся у меня компоненте:
      void __fastcall TForm1::CommPortReceiveData(TObject *Sender, Pointer DataPtr, DWORD DataSize)

      Как его присоединить к потоку.

      Попробуй посредством события
      ExpandedWrap disabled
        void __fastcall TForm1::CommPortReceiveData(TObject *Sender, Pointer DataPtr, DWORD DataSize);
        //...
        //...

      взвести Эвент. А в потоковой процедуре
      ExpandedWrap disabled
        void __fastcall ReceiveData::Execute()
        {
        //...
        //...
        }

      используй ожидание эвента:
      ExpandedWrap disabled
             WaitResult = ::WaitForMultipleObjects (...);
            switch (WaitResult)
             {
              case WAIT_OBJECT_0:
        //..
              break;
         
              case WAIT_OBJECT_0+1:
        //..
              break;
         
              case WAIT_OBJECT_0+2:
        //..
              break;
        //..
        //..

      Возможно, других нужных эвентов тоже.

      И, конечно, все это удобнее делать в одном классе - "CommPortAsync" - "КоммПортАсинхронный".
      Это потому удобно, что ::WaitForMultipleObjects может сама ожидать события приема байт.
      Смастерим "ребенка" от TThread и легко решим проблему.
      ;)
      Сообщение отредактировано: ЫукпШ -
        А что за компонента? Если не твоя, то большинство из тех, что я знаю, уже имеют встроенные потоки.
          А почему не использовать WaitForSingleObject вместо WaitForMultipleObjects?
            Цитата misyachniy @
            А почему не использовать WaitForSingleObject вместо WaitForMultipleObjects?

            Использовать безусловно можно.
            Но я привел вариант более общего случая.
            Когда я писал класс-CommPort мне понадобился именно WaitForMultipleObjects.

            Имеется и другое соображение: минимум - это 2 события.
            Одно событие - для приема байт.
            2-е событие - для нормального завершения потока.

            Так что Multiple на мой взгляд лучше подходит.
            ;)
              Понятно. Я нашел такой пример c while (bSomeCondition)

              unsigned __stdcall CaptureThreadFunc( void * arg) // Поток, готовящий данные
              {
              while (bSomeCondition)
              {
              WaitForSingleObject(m_hEventForCaptureTh,INFINITE); // Ждем своего события
              ... // Готовим данные
              SetEvent(hEventForTransmitTh); // Разрешаем работать второму потоку
              }
              _endthreadex( 0 );
              return 0;
              };


              Если даже поменять условие bSomeCondition поток не будет завершен, юудет ждать WaitForSingleObject.

              Тему можно закрыть.
                Что-то я поспешил с закрытием темы.
                Объявил два события для удобства сделал дефайны.
                ExpandedWrap disabled
                  HANDLE hParcerThreads[2];
                  #define eStopParcer   hParcerThreads[0]
                  #define eResumeParcer hParcerThreads[1]
                   
                  //при создании формы
                  // Создаем два события с автосбросом, со сброшенным начальным состоянием
                  eStopParcer=CreateEvent(NULL,FALSE,FALSE,NULL);
                  eResumeParcer=CreateEvent(NULL,FALSE,FALSE,NULL);
                  // создаем поток разборщика пакетов
                  tParcer= new TParcerData(true);
                   
                  // tParcer->Priority = tpLower; // set the priority lower than normal
                  tParcer->Resume(); // now start the thread running
                   
                  //по приему пакета взвожу событие
                  SetEvent(eResumeParcer);
                   
                  //Взводиться только один раз(доходит оператора switch)
                   
                  WaitResult= ::WaitForMultipleObjects(2, hParcerThreads, FALSE, INFINITE );
                  switch (WaitResult)

                Где нужно править?

                !
                -------------------------------------------
                Используйте теги [СODE][/CODE] для оформления кода
                Сообщение отредактировано: Adil -
                  Цитата misyachniy @
                  Где нужно править?

                  Не понял - в чем именно проблема ?

                  Допустим, работает протоковая процедура:
                  ExpandedWrap disabled
                    //---------------------------------------------------------------------------
                    int WINAPI TThreadChild::Execute ()
                    {
                     for (;;)
                     {
                      if ( GetTerminate () )  break;        
                         WaitResult = ::WaitForMultipleObjects
                         (
                          2,        // number of handles in the object handle array
                          hParcerThreads, // pointer to the object-handle array
                          false,    // wait flag
                          5000      // time-out interval in milliseconds
                         );
                     
                         switch (WaitResult)
                         {
                          case WAIT_OBJECT_0:
                    // тут принимаем байты - рабочее сосояние
                          break;
                     
                          case WAIT_OBJECT_0+1:
                    // состояние выхода
                          SetTerminate();
                          break;
                     
                     
                          case WAIT_TIMEOUT:
                          break;
                         }
                     }
                    return 0;
                    }

                  Когда взводится "рабочий" эвент, начинается некая полезная работа.
                  Когда обработка заканчивается, потоковая процедура снова "WAIT".
                  Если надо ликвидировать поток, выставляется второй эвент.
                  Вот собственно и вся структура.
                  (Билдером я это сейчас не компилировал, возможны мелкие огрехи)
                  Сообщение отредактировано: ЫукпШ -
                    Вопрос в том что я взвожу событые каждый раз по приему пакета.
                    ExpandedWrap disabled
                      SetEvent(eResumeParcer);

                    А присвоение WaitResult происходит только один раз
                    ExpandedWrap disabled
                      WaitResult= ::WaitForMultipleObjects(2, hParcerThreads, FALSE, INFINITE );

                    Может происходит накладка и взводиться событие которое уже во взведенном состоянии?
                      Цитата misyachniy @
                      Может происходит накладка и взводиться событие которое уже во взведенном состоянии?

                      Если что то "не так", то проблема конечно есть. ;)
                      Но если событие не сбрасывается, то Wait не будет больше ждать никогда.
                      Но если Wait запустился хоть один раз, значит событие будет сброшено.
                      (Если эвент спрограммирован на автоматический сброс)
                      Теоретически можно предполагать, что взвод 2-й раз происходит
                      до начала выхода Wait из спячки. Тогда возможно пакеты будут теряться.

                      У меня такого не было. Но тут надо расчитывать возможности твоей программы.
                      Попробуй для эксперимента снизить частоту взвода событий.
                      Что будет ?
                        Через WaitForSingleObject. у меня работала программа.
                        Но чтобы избежать ситуации как в посте №6 переписал под WaitForMultipleObjects
                        Прийдется наверное вернуть все обратно.
                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0434 ]   [ 16 queries used ]   [ Generated: 2.05.24, 21:18 GMT ]