如何确保某些代码每 1 秒运行不超过 1 次?

Posted

技术标签:

【中文标题】如何确保某些代码每 1 秒运行不超过 1 次?【英文标题】:How to make sure that certain code is not run more than 1 every 1 seconds? 【发布时间】:2011-09-15 05:20:08 【问题描述】:

我有一个程序可以从网上下载大量文件

我有几个线程正在下载数据。

每个数据被调用后,我需要更新托管对象上下文

如果 10 个线程大约同时完成加载,则托管对象上下文将运行 10 次。

事实上,我只需要运行一次。

我想做的是创建一个接受块的方法。

我应该怎么做才能创建一个接收块的函数,但是如果该块在不到 1 秒前运行,它将不会运行该块,而是将第二次运行推迟到 1 秒,无论多久函数被调用。

【问题讨论】:

【参考方案1】:

Mike Ash 已经为此实现了timer class。

您需要使用行为类型对其进行初始化,具体取决于您想要的确切行为:

MABGTimerDelay 意味着每次您调用 afterDelay:1.0 do:^ /*code*/ 时,它都会将触发日期设置回去,这样它只会在 last 调用之后整整一秒运行。 MABGTimerCoalesce 意味着每次您调用 afterDelay:1.0 do:^ /*code*/ 时,它都会将触发日期设置回去,这样它只会在 first 调用后整整一秒运行。

如果它已经运行,这两种行为都允许你再次运行它,但只有在延迟再次过去之后。

【讨论】:

【参考方案2】:

如果运行的块总是相同的,您可以在一秒的时间间隔内运行一个循环来检查布尔值,并且只有在布尔值为 YES 时才执行该块。像这样的:

    BOOL needsUpdate;
    -(void) loop 
    if (needsUpdate) 
        //Run Block
        needsUpdate = NO;
    
    [self performSelector:@selector(loop) withObject:nil afterDelay:1.0];
    

当线程完成加载后,您只需设置needsUpdate = YES,然后循环负责其余的工作。

【讨论】:

【参考方案3】:

当一个线程完成调用主线程中的方法。在该方法中,制作一个延迟 1 秒的计时器。

- (void)threadDidFinish

    if (_saveTimer != nil)
    
        _saveTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(saveTimerDidFire) userInfo:nil repeats:NO];
    


- (void)saveTimerDidFire

    [_saveTimer invalidate];
    _saveTimer = nil;

    // save the changes

此代码将确保无论调用 threadDidFinish 的次数如何,您都会每秒保存一次。 NSTimer* _saveTimer 是一个实例变量。

【讨论】:

以上是关于如何确保某些代码每 1 秒运行不超过 1 次?的主要内容,如果未能解决你的问题,请参考以下文章

如何每 100 毫秒执行不超过一次的某些类方法?

在 ASP.NET Web API 中创建一个线程每 X 秒执行一次特定代码

MS Excel - 如何每 5 秒自动刷新一次单元格?

Xamarin Forms:即使应用程序在后台,如何每 x 秒运行一次服务?

处理程序每​​ 5 秒运行一次任务 Kotlin

如何设置每 10 秒刷新一次位置的间隔?