You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust定时器未在指定超时后触发的问题排查

Rust定时器回调未执行的问题排查与解决

我在使用Rust的timer库(版本0.2.0)时遇到问题,定时器回调始终未执行,即使调整超时时间(包括设为0)也无效。测试代码如下:

use std::sync::{Arc, Mutex};

use timer::Timer;

struct Counter {
    value: i32,
}

impl Counter {
    fn new() -> Self {
        Self { value: 0 }
    }

    fn increment(&mut self) {
        self.value += 1;
    }

    fn get_value(&self) -> i32 {
        self.value
    }
}

#[test]
fn test_1() {
    let counter = Arc::new(Mutex::new(Counter::new()));
    let counter_clone_1 = Arc::clone(&counter);
    let counter_clone_2 = Arc::clone(&counter_clone_1);

    // Arrange
    let callback = {
        move || {
            println!("Callback executed");
            counter_clone_1.lock().unwrap().increment();
        }
    };

    let timer = Timer::new();
    println!("Timer created");
    timer.schedule_with_delay(chrono::Duration::seconds(2), callback);

    // Assert initial value
    println!("Initial assert");
    assert_eq!(counter_clone_2.lock().unwrap().get_value(), 0);

    // Act
    println!("Sleeping for 4 seconds");
    std::thread::sleep(std::time::Duration::new(4, 0));

    // Assert incremented value
    println!("Final assert");
    assert_eq!(counter.lock().unwrap().get_value(), 1);
}

运行结果显示回调未触发,最终断言失败:

Timer created
Initial assert
Sleeping for 4 seconds
Final assert
thread 'missed_ping_timer_tests::test_1' panicked at tests\missed_ping_timer_tests.rs:51:5:
assertion `left == right` failed
  left: 0
 right: 1

我的Cargo.toml配置:

[dependencies]
timer = "0.2.0"
chrono = "0.4.39" 

问题根源:chrono版本不兼容

timer 0.2.0依赖的是chrono 0.2.x版本,但你在Cargo.toml中指定了chrono 0.4.39。这两个版本的chrono::Duration是完全不同的类型(即使结构相似),导致你传递给schedule_with_delay的超时时间被错误解析,实际延迟远超过预期,因此回调在测试的4秒内不会执行。

另外,即使版本兼容,timer 0.2.x的设计也需要注意:Timer实例必须保持存活直到回调执行完毕,否则实例被drop时会立即终止内部定时器线程,取消所有未执行的任务。

解决方案

方案1:对齐chrono版本

将chrono版本降级到与timer 0.2.0兼容的0.2.x系列,修改Cargo.toml:

[dependencies]
timer = "0.2.0"
chrono = "0.2.33"

方案2:升级timer到兼容chrono 0.4的版本

timer 0.3.x及以上版本支持chrono 0.4,修改Cargo.toml:

[dependencies]
timer = "0.3.0"
chrono = "0.4.39"

此版本API与0.2.x基本兼容,你的测试代码无需大幅修改即可正常运行。

方案3:替换为原生线程实现(无第三方依赖)

如果不想依赖timer库,可以直接用标准库线程实现定时器逻辑,避免版本兼容问题:

use std::sync::{Arc, Mutex};

struct Counter {
    value: i32,
}

impl Counter {
    fn new() -> Self {
        Self { value: 0 }
    }

    fn increment(&mut self) {
        self.value += 1;
    }

    fn get_value(&self) -> i32 {
        self.value
    }
}

#[test]
fn test_1() {
    let counter = Arc::new(Mutex::new(Counter::new()));
    let counter_clone_1 = Arc::clone(&counter);
    let counter_clone_2 = Arc::clone(&counter_clone_1);

    // 用标准库线程实现定时器
    std::thread::spawn(move || {
        std::thread::sleep(std::time::Duration::seconds(2));
        println!("Callback executed");
        counter_clone_1.lock().unwrap().increment();
    });

    // Assert initial value
    println!("Initial assert");
    assert_eq!(counter_clone_2.lock().unwrap().get_value(), 0);

    // Act
    println!("Sleeping for 4 seconds");
    std::thread::sleep(std::time::Duration::new(4, 0));

    // Assert incremented value
    println!("Final assert");
    assert_eq!(counter.lock().unwrap().get_value(), 1);
}

验证说明

选择方案1或2后,你的原代码中的回调会在2秒后正常执行,最终断言会通过。方案3的原生实现更直接,无需依赖第三方库,适合简单的定时场景。

内容的提问来源于stack exchange,提问作者Umberto Gotti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 09:27:01