簡體   English   中英

如何執行多次調用的函數,只執行一次!

[英]How to execute a function called many times, only once !

有沒有辦法執行一次只調用一次的函數? 我有一個函數,在一個排序容器中添加項目,並有代碼,更新列表和其他窗口(GUI人員)。 所以,如果我必須添加一百萬個項目(其數量無法分辨,任何人都可以從任何地方調用該函數),GUI更新機制將被調用多次...有沒有辦法告訴appart連續函數執行(並忽略它)來自不連續? 是否有一種安全的方法在上次調用add-item函數時,在一個時間間隔內執行更新機制?

謝謝。

Roesone,你的代碼壞了。 它拒絕你寫它的嘗試,因為它知道它是錯的。 你可能會發現一些蹩腳的黑客會發出你想要的行為 - 現在。 但那個解決方案將是一個黑客; 脆弱,容易出錯,難以維護。 特別容易受到漣漪效應的影響。 只要你在某個地方對某個遠程接觸這個功能的東西做了一個小的改動,那個蹩腳的黑客就會破壞,你會比現在更糟糕。

不,這里的解決方案不是找到一個可行的黑客。 解決方案是修復您的代碼。 從根本上說,這意味着編寫兩個函數。 一個將數據插入容器,另一個完全獨立的函數將數據呈現給屏幕。 然后,您可以專門為這些方法設計機制。 例如,您可以每秒更新屏幕十次,同時允許插入沒有限制。

做你自己,你的同事和自由世界,並修復你破碎的代碼。

你可以放一個static bool ,如果為true,退出函數。

如果您想要添加許多項目的情況下關閉“重繪”(GUI更新),該怎么辦?

// add one item:
window.add_item()

// add many items:
window.set_redraw(false)
window.add_many_items()
window.set_redraw(true)

然后你的add_item函數只是在更新GUI之前檢查標志。 添加一個項目的簡單情況保持不變。

可能更好地手動更新觸發器。

如果您使用計時器並使用Win32 API,則可以使用SetTimer方法啟動計時器,以便在每次調用函數時觸發。 SetTimer的行為是,如果在第一次調用關閉之前使用相同的TimerID再次調用它,則計時器將被重置。 因此,每次調用函數時都可以調用SetTimer,並且可以保證定時器僅在最后一次調用后“n”毫秒觸發。

  UINT_PTR timerID = SetTimer(NULL, someUniqueID, 1000, yourCallback);

記得隨后打電話給KillTimer進行清理。

SetTimer的MSDN

您需要在一段時間內聚合容器的更新,然后在此時間段之后執行更新操作(說起來容易做起來難!)。 重要的是要清楚哪些行為適合聚合在一起,哪些不合適。

真正的一點是,如果您擔心某個區域的性能,那么您應該集中精力進行這方面的工作,例如,如果您以遠高於UI顯示更新頻率(或高於您的頻率)的頻率執行UI更新操作實際需要)然后這是應該在時間間隔內聚合它的更新的代碼。

您還需要確保不要使數據結構過時,以便及時對最后一個通知采取行動,即使下一次更新不會發生很長時間。

最好的解決方案(恕我直言)是.NET用於大多數控件的解決方案:

創建某種“SuspendLayout”方法,該方法設置一個布爾值,只有在未設置的情況下才更新GUI。 添加“ResumeLayout”,然后更新GUI。

這樣,如果你班級的用戶只更新一個項目,他就不需要改變任何東西,如果他多次更新,他可以這么說,你的班級就不用擔心了。

這也允許您在必要時優化批量更新,即在列表中預先分配更多空間。 您還可以向SuspendLayout添加一個覆蓋,指示將添加的項目數(SuspendLayout(int forNumberOfItems)),以便您可以使用正確的空間量初始化列表。

這取決於您用於GUI的框架。

基本上,它歸結為具有以下偽代碼:

bool g_isValueModified = false ;
Value g_value ;

void setValue(Value value)
{
   g_value = value ;
   g_isValueModified = true ;
}

void updateValueOnGUI()
{
   if(g_isValueModified)
   {
      g_isValueModified = false ;

      // put here the code to set the value in the GUI widget
   }
}

方法setValue應該根據需要調用,而方法updateValueOnGUI應該被updateValueOnGUI ,比如每10或100ms updateValueOnGUI一次。

要實現此異步行為,可以:

  • 如果在原始Win32上,使用Win32計時器來調用您的WinProc
  • 在高級GUI框架上,使用計時器
  • 或者,在高級GUI框架上,使用兩個單獨的線程,一個用於代碼執行(使用set方法),另一個用於GUI執行(執行更新),確保以多線程安全方式(即鎖定)寫入/讀取g_value和g_isValueModified ,關鍵部分等)。

暫無
暫無

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

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