繁体   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