如何执行多次调用的函数,只执行一次!

时间:2010-04-01 13:04:13

标签: c++ function delay

有没有办法执行一次只调用一次的函数?我有一个函数,在一个排序容器中添加项目,并有代码,更新列表和其他窗口(GUI人员)。所以,如果我必须添加一百万个项目(其数量无法分辨,任何人都可以从任何地方调用该函数),GUI更新机制将被调用多次...有没有办法告诉appart连续函数执行(并忽略它)来自不连续?是否有一种安全的方法来执行更新机制只在最后一次调用 add-item 函数时,在一个时间间隔内?

谢谢。

8 个答案:

答案 0 :(得分:11)

Roesone,你的代码坏了。它拒绝你写它的尝试,因为它知道它是错的。你可能会发现一些蹩脚的黑客会发出你想要的行为 - 现在。但那个解决方案将是一个黑客;脆弱,容易出错,难以维护。特别容易受到涟漪效应的影响。只要你的代码在远程接触这个功能的某个地方做了一个小的改动,蹩脚的黑客就会破坏,你现在会比现在更糟糕。

不,这里的解决方案不是找到一个可行的黑客。解决方案是修复您的代码。从根本上说,这意味着编写两个函数。一个将数据插入容器,另一个完全独立的函数将数据呈现给屏幕。然后,您可以专门为这些方法设计机制。例如,您可以每秒更新屏幕十次,同时允许插入没有限制。

帮助你自己,你的同事和自由世界,并修复你破碎的代码。

答案 1 :(得分:6)

你可以放一个static bool,如果为真,退出该函数。

答案 2 :(得分:2)

如果您想要添加许多项目的情况下关闭“重绘”(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之前检查标志。 添加一个项目的简单情况保持不变。

答案 3 :(得分:1)

可能更好地手动更新触发器。

答案 4 :(得分:0)

如果您使用计时器并使用Win32 API,则可以使用SetTimer方法启动计时器,以便在每次调用该函数时触发。 SetTimer的行为是,如果在第一次调用关闭之前使用相同的TimerID再次调用它,则计时器将被重置。因此,每次调用函数时都可以调用SetTimer,并且可以保证定时器只会在最后一次调用后的“n”毫秒内触发。

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

请记得随后致电KillTimer进行清理。

MSDN for SetTimer

答案 5 :(得分:0)

您需要在一段时间内聚合容器的更新,然后在此时间段之后执行更新操作(说起来容易做起来难!)。重要的是要清楚哪些行为适合聚合在一起,哪些不合适。

真正的一点是,如果你担心某个地区的表现,那么你应该把注意力集中在这方面。如果您以远高于UI显示更新频率(或高于实际需要的频率)的频率执行UI更新操作,那么这就是应该在时间间隔内聚合它的更新的代码。

您还需要确保不要使数据结构过时,以便及时对最后一个通知采取行动,即使下一次更新不会发生很长时间。

答案 6 :(得分:0)

最好的解决方案(恕我直言)是.NET用于大多数控件的方法:

创建某种“SuspendLayout”方法,该方法设置一个布尔值,只有在未设置的情况下才更新GUI。添加“ResumeLayout”,然后更新GUI。

这样一来,如果你班级的用户只更新一个项目,他就不需要改变任何东西,如果他多次更新,他就可以这样说,你的班级就不用担心了。

这也允许您在必要时优化批量更新,即在列表中预先分配更多空间。您还可以向SuspendLayout添加一个覆盖,指示将添加的项目数(SuspendLayout(int forNumberOfItems)),以便您可以使用正确的空间量初始化列表。

答案 7 :(得分:0)

这取决于您用于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应调用,例如,每10或100毫秒调用一次。

要实现此异步行为,请执行以下操作之一:

  • 如果在原始Win32上,使用Win32计时器来调用WinProc
  • 在高级GUI框架上,使用计时器
  • 或者,在高级GUI框架上,使用两个单独的线程,一个用于代码执行(使用set方法),另一个用于GUI执行(执行更新),确保以多线程安全的方式写入/读取g_value和g_isValueModified (即锁,关键部分等)。