2015-04-20 6 views
0

Я пытаюсь создать dll (в Clr flavor), чтобы подать приложение Windows с котировками внутридневных акций. DLL загружается приложением для акций, тогда одна из его экспортируемых функций запустит загрузчик/производитель для получения данных. На втором этапе, как только данные, полученные DLL, обновитель/потребитель уведомит приложение запаса через SendMessage.SendMessage не работает

Я тестировал во многих отношениях, что загружаемая часть работает должным образом (с поддержкой потоков или без нее), поэтому получение данных не представляет проблемы. В случае с единственной итерацией (test1 ниже), сразу после доступных котировок моментальных снимков, программа обновления успешно выполняет свою миссию, и пользовательский интерфейс Windows обновляется. Теперь, чтобы получать новые кавычки, я помещал вызовы функции загрузчика и обновления в цикл (test2 ниже). На этот раз загрузчик работает непрерывно, но SendMessage в обновлении висел там, оставляя пользовательский интерфейс Windows не обновленным, пока он не выйдет из цикла.

Вот тестовые коды и код обновления (давайте оставим в стороне downloder, как мы знаем, что она работает):

// test1: single iteration, sequential, simple insert only 
// result: will update the stock app after quote download 
void test1(HWND hwnd, UINT Msg) 
{ 
    producer->DownloadStocks(); 
    prepareData(hwnd, Msg, 100); 
} 

// test2: one iteration of insert followed by updates upon quote download 
// result: will update the stock app ONLY after it is out of the while loop 
//   update in test1 is blocked, too. 
void test2(HWND hwnd, UINT Msg) 
{ 
    test1(hwnd, Msg); 
    int i = 0; 
    while (i<10) 
    { 
     producer->DownloadStocks(); 
     prepareData(hwnd, Msg, 100); 
     i++; 
    } 
} 


    void prepareData(HWND hwnd, UINT Msg, int timeout) 
    { 

     DateTime origin = DateTime(1970, 1, 1, 0, 0, 0, 0); 
     RCV_DATA rcv_data; 
     float vv = 0; 
     rcv_data.m_bDISK = FALSE; 
     rcv_data.m_nPacketNum = 1; 
     rcv_data.m_wDataType = RCV_REPORT; 
     RCV_REPORT_STRUCTEx data; 
     data.m_fBuyPrice[1] = 0; 
     data.m_fBuyVolume[1] = 0; 
     ...... 
     data.m_wMarket = (WORD)NQ_MARKET_EX; 

     while (consumer->received_data()) 
     { 
      Console::WriteLine("*********************************"); 

      while (consumer->NextRow()) 
      { 

       sprintf(data.m_szLabel, "%s", consumer->GetValue("symbol")); 
       ....... 
       data.m_fSellPrice[0] = getVal("ask"); 
       data.m_fSellVolume[0] = getVal("asksize"); 

       rcv_data.m_pReport = &data; 
       printf("\nsending update for %s", data.m_szLabel); 
       SendMessage(hwnd, Msg, (WPARAM)RCV_REPORT, (LPARAM)&rcv_data); 

      } 
     } 

    } 

Я знаю, что SendMessage находится в режиме синхр. Заблокировано ли что-то или обработка сообщений слишком медленная? Что я могу сделать, чтобы обойти это? Должен ли я рассматривать потоки как для загрузчика, так и для обновления? Любая помощь будет оценена по достоинству.

+0

ваше окно обновляется в следующем событии Paint, которое он сможет обрабатывать, если поток является бесплатным. В одном потоке только после завершения цикла/функции он может получать/обрабатывать другие события. Вам необходимо выполнить многопоточность. –

+0

Тупик - это общая опасность при использовании SendMessage(). Вам нужно будет использовать отладчик, узнать, что делает поток, которому принадлежит окно. Всегда предпочитайте PostMessage(). –

+0

@ Ашиш Неги, я попробовал pthread, используя шаблон потребителя/продюсера. Это не сработает. – Ben

ответ

0

Поскольку вы уже посылает данные в поток пользовательского интерфейса с помощью SendMessage, вы можете отправить WM_PAINT событие в этом окне также. Вы можете сделать это с помощью UpdateWindow или InvalidateRect. Это приведет к обновлению представления после ваших обновлений.

Cross нить перерисовки события объясняются здесь с некоторым кодом: redraw-from-another-thread

Вы должны держать UI нить всегда бесплатно интерактивности. Поэтому выполняйте свои блокирующие работы (например, загрузку) в фоновом потоке. std::thread может работать кросс-платформенный, если вы можете использовать c++11.

+0

Прошло некоторое время. Наконец, я решил большинство проблем. Для этого я создаю поток для обновления данных «SendMessage» в пользовательском интерфейсе через HWND и предопределенное сообщение. Итак, спасибо за предложения от всех, особенно от @Ashish Negi – Ben

+0

Рад, что это помогло .. :) Великая настойчивость @Ben –

0

цикл «while» и вызываемые функции в этом цикле забивают процессор.

предлагает добровольное освобождение ЦП на каждой итерации цикла while.

возможно по телефону nsleep()

+0

гул, размещение сна в разных местах различной длины, похоже, не разблокирует обновление. – Ben

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