程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 使用PostThreadMessage 與線程進行大數據量的通訊

使用PostThreadMessage 與線程進行大數據量的通訊

編輯:.NET實例教程

PostThreadMessage是一個線程體發送一個消息到指定的線程ID,其原型如下:

BOOL PostThreadMessage(          
                    DWord idThread,
                    UINT Msg,   
                    WPARAM wParam,    
                    LPARAM lParam
);    這個函數既可以發送消息給工作線程,也可以發送給UI線程
問題1:這個函數成功執行的前提是目標線程已經有了一個消息隊列。否則函數會失敗。 通過GetLastError()函數可以獲得錯誤代碼1444。
 
這個問題的解決方式有以下兩個:
1 不斷調用PostThreadMessage函數,直到函數成功。 這是因為當線程收到這樣的函數以後,會自動創建消協隊列。
2 創建Event對象,讓PostThreadMessage等待目標線程創建一個消息隊列。而目標線程可以通過調用PeekMessage強制系統創建一個message queue。
  示例代碼如下:

假設mainAPP是發送線程ThreadA是接受線程
/*mainAPP.cpp*/
……
hStartEvent = ::CreateEvent(0,FALSE,FALSE,

0); //create thread start event
if(hStartEvent == 0)
{
          printf("create start event failed,errno:%d\n",::GetLastError());
          return 1;
}
::WaitForSingleObject(hStartEvent,INFINITE);
CloseHandle(hStartEvent);
if(!PostThreadMessage(threadaID, WM_MESSAGE_A,0,0))
{
          _tprintf(_T("post error! %d\n"), GetLastError());
          return 1;
}
……
ThreadA是接受線程

/* ThreadA */
MSG msg;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
if(!SetEvent(hStartEvent))
{
          printf("set event error,%d\n",GetLastError());
          return 1;
}
while(true){
          if(GetMessage(&msg, 0,0,0)) {
                    switch(msg.message){
                              case WM_MESSAGE_A:
                               ……
                               break;
                              }
                    }
          }
}
 
問題2:消息不能包含大量數據。

解決如下

1 發送線程在堆中非配一個大量數據 2 消息中包含堆的指針,然後進行發送 3 目標線程序收到消息後,把發送線程序分配的堆釋放。

示例程序如下:
/*構造信息如下*/
char* pInfo = new char[MAX_INFO_SIZE]; //發送線程在這裡創建了一個堆
sprintf(pInfo,"msg_%d",++count);
PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,0)//post thread msg
 
/*解釋信息如下*/
if(GetMessage(&msg,0,0,0)) //get msg from message queue
{
             switch(msg.message)
             {
             case MY_MSG:
             char * pInfo = (char *)msg.wParam;
             printf("recv %s\n",pInfo);
            delete[] pInfo; //這裡釋放了發送線程裡創建的堆
             break;
             }
}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved