主頁 > 軟體工程 > MessageBox會導致異步網路接收函式不被觸發嗎?

MessageBox會導致異步網路接收函式不被觸發嗎?

2020-09-23 00:13:05 軟體工程

近期在用MFC做一個軟體,軟體與服務器通訊,服務器與客戶端均在本機,客戶端下發指令給服務器,服務器上發相應內容給客戶端。發送由用戶點擊按鈕,呼叫send函式發送;接收則采用異步接收,重寫了CAsyncSocket類的Onreceive函式。希望的效果是下發之后500ms內收到相應回復資料。
目前遇到一個問題,想做一個用戶確認的功能,目前做法是用MessageBox彈框,確認之后再進行下發,下發在另外開啟的執行緒中進行。
但是發現加入了這個MessageBox之后,經常會出現點擊確認之后Onreceive函式不被呼叫,但是在下發超時之后(也就是發送失敗之后)才會收到資料。從服務器端日志來看,服務器端確實在合適的時間將資料上發了,但是就是無法觸發,最后一次發送失敗之后收到正確資料。因為是本機網路,不考慮網路延時。
剛開始以為網路有問題,一直找不到原因。直到偶然把提示的確認框相關代碼注釋掉之后發現這個Onreceive函式可以被正常觸發。所以感覺是MessageBox這邊出了問題。


t = MessageBox(this->GetSafeHwnd(),"確認下發引數?","下發引數",MB_YESNO | MB_ICONWARNING);
if(t == IDNO) return;

所以不知道這種情況由何引起,又該如何解決?請大家幫忙看看

uj5u.com熱心網友回復:

我也遇到過 你可以在界面上換個控制元件顯示資訊  Messagebox會彈出來的時候 你是接收不到資料的

uj5u.com熱心網友回復:

你試下用afxmessagebox看看

uj5u.com熱心網友回復:

messafebox會可能影響訊息回圈。導致aocket色訊息也被影響

uj5u.com熱心網友回復:

我又確實需要根據用戶的選擇來決定是否下發,所以此處必須得有阻塞。請問大家有沒有其他的控制元件可以解決這個問題呢?

uj5u.com熱心網友回復:

下發在另外開啟的執行緒中進行   是什么意思?

要注意在默認情況下,CAsyncSocket和CSocket物件不能跨執行緒使用。

uj5u.com熱心網友回復:

就是在用戶確認過messageBox之后,呼叫發送函式,函式中啟動執行緒下發引數,用send。
執行緒會等待一段時間(這里設計的是500ms),這段時間內如果收到資料,標志位置位,退出執行緒。
在發送函式中等待執行緒結束,使用的是waitforMultipleobjects,同時也建立有訊息回圈保證訊息不被阻塞。
等待執行緒結束部分是這么寫的:

        RefreshResult=AfxBeginThread(DownloadParaThread,(LPVOID)&index); 
if (RefreshResult != NULL) 

DWORD dwRet=0;
MSG msg;  
while (TRUE)  
{  
dwRet = MsgWaitForMultipleObjects (1, &RefreshResult->m_hThread,   FALSE, INFINITE, QS_ALLINPUT);  
if(dwRet==WAIT_OBJECT_0)
break;
else if(dwRet==WAIT_OBJECT_0 + 1)
{
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);  
DispatchMessage(&msg); 
}
else
break;
}
RefreshResult = NULL;



直觀上感覺是在下發send函式呼叫之后,Onreceive函式就無法被觸發,但是偶爾又會有被觸發的情況,也不是每次都失敗,只是失敗的概率比較大。但是如果將前面MessageBox代碼段刪掉之后,OnReceive函式就可以正常觸發。所以才定位到MessageBox的影響。你們感覺如何呢?

uj5u.com熱心網友回復:

而且我不僅僅是在MessageBox存在的時候不能觸發,關掉MessageBox之后也不能觸發。

uj5u.com熱心網友回復:

把messageBox提前放到其他地方,或者在界面UI執行緒中處理

uj5u.com熱心網友回復:

自己做個 Modeless 對話框 (create), 不行嗎 ?

uj5u.com熱心網友回復:

MessageBox處理結束之后才會呼叫函式啟動執行緒,就是感覺是不是MessageBox雖然通過點擊OK或者cancek結束了但是它還是會影響到后面執行緒的啟動。

uj5u.com熱心網友回復:

我正準備自己畫一個對話框,然后DoModal呼叫,看看是否存在問題。

uj5u.com熱心網友回復:

是不是要 呼叫 WM_CANCELMODE ??
 void CCancelModeDlg::OnSetfocusEdit2() 
{
if(!FindWindow(0,"yyy"))// change : AFX_IDS_APP_TITLE="yyy" 
{
AfxMessageBox("SetfocusEdit2");
// w.o this, the cursor is 'I' anywhere ,means focus in edit2 !!!
// mouse has captured by edit2
m_Edit2.PostMessage(WM_CANCELMODE,0,0);
}
}

uj5u.com熱心網友回復:

自己做了一個對話框,用DoModal()啟動,發現Onreceive函式還是會被推遲觸發的情況。不知道WM_CANCELMODE 是什么意思呢??

uj5u.com熱心網友回復:

SUMMARY
In the Microsoft Windows graphical environment, the WM_CANCELMODE message informs a window that it should cancel any internal state. This message is sent to the window with the focus when a dialog box or a message box is displayed, giving the window the opportunity to cancel states such as mouse capture. 

When a control has the focus, it receives a WM_CANCELMODE message when the EnableWindow function disables the control or when a dialog box or a message box is displayed. When a control receives this message, it should cancel modes, such as mouse capture, and delete any timers it has created. A control must cancel these modes because an application may use a notification from the control to display a dialog box or a message box. 

The DefWindowProc function processes WM_CANCELMODE by calling the ReleaseCapture function, which cancels the mouse capture for whatever window has the capture. The DefWindowProc function does not cancel any other modes.

uj5u.com熱心網友回復:

CAsyncSocket有做防無限重入,避免你這樣MessageBox阻塞之后又接受到新訊息導致無數個MessageBox被彈出來。

你應該重新考慮下界面設計,比如用狀態欄或者串列視圖來顯示資訊。

uj5u.com熱心網友回復:

“將前面MessageBox代碼段” 改為 afxDump (不柱塞)看看

uj5u.com熱心網友回復:

換TRACE

uj5u.com熱心網友回復:

總結一下,是因為沒有做好訊息泵,沒有把所有的資訊都傳入到訊息回圈,有一段代碼如下:
while (TRUE)  
{  
//wait for m_hThread to be over,and wait for  
//QS_ALLINPUT(Any message is in the queue)  
dwRet = MsgWaitForMultipleObjects (1, &cThread->m_hThread,   FALSE, INFINITE, QS_ALLINPUT);  
switch(dwRet)  
{  
case WAIT_OBJECT_0:   
break; //break the loop  
case WAIT_OBJECT_0 + 1:  
//get the message from Queue  
//and dispatch it to specific window  
while(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
  
continue;  
default:  
break; // unexpected failure  
}  
break;  
}  
cThread = NULL;


紅色部分就是問題的關鍵,因為之前沒有加那個回圈,導致的后果就是一旦出現對話框,將msg回圈占用,就會導致異步網路接收函式的阻塞,最終導致問題的產生,加入回圈之后問題解決,對話框的彈出與否不再影響網路的異步接收。

到這里看起來似乎問題已經結束,但是經過這個問題,我發現自己對于一些技術的理解還是太膚淺了,找到解決方案之后沒辦法去弄明白其中的具體道理,比如為什么加入了while回圈之后訊息回圈就可以正常運行了,之前對話框的出現是為什么會導致這些問題的產生也都只是個人感覺問題所在,并沒有參考書籍文獻材料,以前看侯俊杰前輩的《深入淺出MFC》也只是略過一眼,沒有去仔細專研其中細節深奧的部分。。
這里希望有相關經驗或者對這個問題感興趣的朋友們能夠不吝賜教,講解一下關于MFC訊息回圈的原理以及什么可能會影響訊息回圈。

uj5u.com熱心網友回復:

 我認為你的異步設計有問題,導致了復雜的解決方案。
CAsycSocket實際上不是在作業者執行緒中等待接收資料的,它是運行在主執行緒環境中的,也就是和你的MessageBox所在的執行緒在一起的。之所以接收是異步的,應該是底層用了Overlapped IO之類的技術,而Overlapped IO的讀寫完成的通知是基于訊息的,MessageBox阻塞了訊息回圈,使得CAsyncSocket不能及時觸發OnReceived。你的解決方案是修改訊息回圈。
我個人不喜歡自定義訊息回圈這種高度依賴OS平臺、造成程式不易讀的技術。我倒以為,你應該將接收程序和發送程序一樣,徹底放到另一個作業者執行緒中。這樣一,不用自定義訊息回圈,有利于以后程式維護,也有利于程式移值到其它平臺;不用CAsyncSocket,代碼邏輯清晰。

uj5u.com熱心網友回復:

另外,覺得樓主異步發送后,等待發送執行緒結束那段代碼太復雜,還用訊息泵(我樓上稱為訊息回圈,不嚴謹)。不如修改下,異步發送執行緒在結束前,清除另一個標志位,這個標志位表明是否在發送等待500ms中。這樣,主執行緒就可以在用戶重復發送前,判斷此標志,如果標志置位,則提示用戶“上一次發送正等回復中”之類的。主執行緒完全不必使用訊息泵。
個人認為,越復雜就越容易出錯,也不易后續維護和擴展,象MsgWaitForMultipleObjects 這種API坑很多的。

uj5u.com熱心網友回復:

MessageBox函式可以阻塞程式的正常執行的,

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/108107.html

標籤:進程/線程/DLL

上一篇:大家寫串口用什么?我過去用的MSCOMM控制元件,現在準備用serialport,發現serialport庫的版本實在太多了。差別也挺大。很多函式不通用。

下一篇:求!teechart 在vs2010中的用法

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more