簡體   English   中英

MFC數據通過PostMessage轉發到主線程

[英]MFC data forwarding to main thread via PostMessage

我有一個C ++ / MFC應用程序,我需要重組。 該應用程序用於處理主線程上的大部分數據,因此阻止輸入,現在我想更改它,所有GUI更新都通過PostMessage完成。

不幸的是,我似乎找不到如何實現這一目標的良好來源。

現在我正在考慮創建一個優先級隊列,使用臨界區保護,一個處理此隊列的工作線程(while(true)),以及將數據指針發送到主線程的PostMessage機制。

使用這種方法讓我害怕的是PostMessage根本不能保證到達主線程,所以,如果我理解正確,就有可能發生內存泄漏。

第二個問題是另一個應用程序可以向我的應用程序發送自定義消息,我的應用程序可能會嘗試取消引用WPARAM或LPARAM作為指針,從而導致AV。

有誰知道這些任務的最佳實踐是什么?

數據可以是用於Web控件的HTML內容,也可以是列表框,下拉列表等的其他內容。

你的消息將會到達那里。 我不確定為什么你認為PostMessage不能保證工作 - 它是。 (編輯:假設PostMessage()返回TRUE!檢查您的返回代碼!)

您希望避免使用隊列在線程之間傳遞數據。 兩個線程訪問的任何隊列都需要受到保護。 在兩側添加硬鎖將序列化您的應用程序。

相反,使用包含數據的new在堆上創建一個數據結構,然后告訴另一個線程“我已經為你獲取了數據,就在這里。” 然后,接收線程獲取該數據指針的所有權,並負責delete它。 這樣做,沒有硬鎖。

現在唯一的訣竅是弄清楚“告訴另一個線程”部分,但這也很容易。

如果要將數據從工作線程發送到主線程,只需使用PostMessage()

worker_thread_proc()
{
// ..

  // Create the data object you're going to pass to the MT
  MyData* data = new MyData;
  data->some_value_ = "foo";

  // Pass it:
  PostMessage(main_wnd, WM_YOU_HAVE_DATA, reinterpret_cast<WPARAM>(data), 0);
}

...主線程處理它,然后刪除數據:

MainWnd::OnYouHaveData(WPARAM wp, LPARAM)
{
  std::auto_ptr<MyData> data(reinterpret_cast<MyData*>(wp));
  my_widget->set_text(data->some_value_); // you get the idea
}

如果您擔心外部應用程序的自定義消息會泄露給您,您可以使用RegisterWindowsMessage()讓Windows為您提供唯一的消息ID - 您唯一的挑戰是為您的消息選擇正確的名稱。

如果您將數據從主線程發送到工作線程,您可以執行與上面相同的操作,除了使用PostMessage()通過牆發送數據,您可以使用QueueUserAPC() (確保您的工作人員是處於可警告的等待狀態 - 讀取鏈接文檔中的備注)或PostThreadMessage()

編輯:

根據您在OP中的評論,現在我理解為什么您擔心PostMessage()不起作用。

是的,Windows消息隊列大小存在硬限制。 默認情況下,隊列中只能有4,000條消息。 (注冊表設置可以將其調整為最大10,000)。

如果隊列已滿,則對PostMessage()任何調用都將失敗並顯示錯誤代碼。 當你檢查GetLastError()(我不記得它現在返回的錯誤代碼)時,很明顯消息隊列已滿。

不要聽起來像母雞,但你真的需要檢查API調用的返回值。 但除此之外,如果你在消息隊列上運行,我會說你的應用程序仍然被破壞了。 當隊列已滿時,您的應用程序將無法呼吸。 屏幕不會畫,你做的任何處理都會陳舊,並且會發生各種不好的事情。 如果您遇到這種情況,您可能需要查看原因。

使用兩個隊列,一個用於發送到工作線程的工作請求,另一個用於返回主線程的結果。 您可以使用PostMessage喚醒主線程並告訴它檢查隊列,但您不需要消息中的任何參數。

我前段時間解決了類似的問題。 我創建了一個單例隊列來保存需要從后台線程流到UI(主)線程的數據(或操作)。 隊列受臨界區保護。 后台線程會將其數據放入隊列並發布消息。 該消息不包含任何數據,它充當一個簡單的喚醒呼叫“嘿,主線程,看看隊列,有你的工作”。

這樣,您就不會冒泄漏任何內存或其他資源的風險; 可以使用它包含的所有數據安全地銷毀隊列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM