Rust异步定时器库async-timer的使用:高效、轻量级的跨平台定时任务调度解决方案
Rust异步定时器库async-timer的使用:高效、轻量级的跨平台定时任务调度解决方案
async-timer简介
async-timer是Rust的异步计时器库,提供定时任务调度功能。它具有以下特点:
- 支持no_std环境
- 最小Rust版本要求:1.36
- 跨平台支持
定时任务(Timed)
async fn job() {
}
async fn do_job() {
let work = unsafe {
async_timer::Timed::platform_new_unchecked(job(), core::time::Duration::from_secs(1))
};
match work.await {
Ok(_) => println!("I'm done!"),
// 可以通过轮询`expired`来重试
Err(expired) => println!("Job expired: {}", expired),
}
}
间隔任务(Interval)
async fn job() {
}
async fn do_a_while() {
let mut times: u8 = 0;
let mut interval = async_timer::Interval::platform_new(core::time::Duration::from_secs(1));
while times < 5 {
job().await;
interval.as_mut().await;
times += 1;
}
}
Q&A
Q: 什么时候会支持async/await?
A: 当async/await支持no_std环境时
完整示例代码
use async_timer::{Timed, Interval};
use std::time::Duration;
use tokio; // 需要tokio或其他异步运行时
#[tokio::main]
async fn main() {
// 定时任务示例
println!("=== 定时任务示例 ===");
timed_example().await;
// 间隔任务示例
println!("=== 间隔任务示例 ===");
interval_example().await;
}
async fn timed_example() {
async fn task() {
println!("定时任务执行中...");
}
let work = unsafe {
Timed::platform_new_unchecked(task(), Duration::from_secs(2))
};
match work.await {
Ok(_) => println!("定时任务完成!"),
Err(e) => println!("定时任务失败: {}", e),
}
}
async fn interval_example() {
async fn periodic_task() {
println!("周期性任务执行...");
}
let mut counter = 0;
let mut interval = Interval::platform_new(Duration::from_secs(1));
while counter < 5 {
periodic_task().await;
interval.as_mut().await;
counter += 1;
}
println!("已完成5次周期性任务");
}
要使用这个库,需要在Cargo.toml中添加以下依赖:
[dependencies]
async-timer = "0.7.4"
tokio = { version = "1", features = ["full"] } # 或其他异步运行时
这个库特别适合需要轻量级、跨平台定时任务调用的异步Rust应用场景。
1 回复
Rust异步定时器库async-timer的使用指南
概述
async-timer
是一个高效、轻量级的跨平台异步定时器库,专为Rust的异步生态系统设计。它提供了简单的API来创建和管理定时任务,适用于需要延迟执行或周期性任务的异步应用场景。
主要特性
- 跨平台支持(Linux/macOS/Windows)
- 零依赖(仅使用标准库和futures)
- 线程安全(可在多线程环境中使用)
- 精确的定时控制
- 与async/await语法无缝集成
安装
在Cargo.toml中添加依赖:
[dependencies]
async-timer = "1.0"
基本使用方法
1. 一次性定时器(Oneshot Timer)
use async_timer::oneshot::Oneshot;
use std::time::Duration;
#[tokio::main]
async fn main() {
// 创建一个3秒后触发的定时器
let timer = Oneshot::new(Duration::from_secs(3));
println!("等待定时器...");
timer.await;
println!("3秒已过!");
}
2. 周期性定时器(Interval Timer)
use async_timer::interval::Interval;
use std::time::Duration;
#[tokio::main]
async fn main() {
// 创建一个每1秒触发一次的定时器
let mut interval = Interval::new(Duration::from_secs(1));
for i in 1..=5 {
interval.next().await;
println!("第 {} 次触发", i);
}
}
3. 取消定时器
use async_timer::oneshot::Oneshot;
use std::time::Duration;
#[tokio::main]
async fn main() {
let timer = Oneshot::new(Duration::from_secs(5));
tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(2).await;
println!("取消定时器");
timer.cancel();
});
match timer.await {
Ok(()) => println!("定时器正常完成"),
Err(_) => println!("定时器被取消"),
}
}
高级用法
与select!宏配合使用
use async_timer::oneshot::Oneshot;
use std::time::Duration;
#[tokio::main]
async fn main() {
let timer = Oneshot::new(Duration::from_secs(3));
let timeout = tokio::time::sleep(Duration::from_secs(5));
tokio::select! {
_ = timer => println!("定时器先触发"),
_ = timeout => println!("超时先触发"),
}
}
动态调整定时器
use async_timer::interval::Interval;
use std::time::Duration;
#[tokio::main]
async fn main() {
let mut interval = Interval::new(Duration::from_secs(1));
for i in 1..=10 {
interval.next().await;
println!("触发 {}", i);
// 每5次后增加间隔时间
if i % 5 == 0 {
interval.set_period(Duration::from_secs(2));
println!("间隔时间增加到2秒");
}
}
}
完整示例demo
下面是一个结合了多种特性的完整示例:
use async_timer::{oneshot::Oneshot, interval::Interval};
use std::time::Duration;
#[tokio::main]
async fn main() {
// 示例1:一次性定时器
println!("--- 一次性定时器示例 ---");
let oneshot = Oneshot::new(Duration::from_secs(2));
oneshot.await;
println!("一次性定时器触发!\n");
// 示例2:周期性定时器
println!("--- 周期性定时器示例 ---");
let mut interval = Interval::new(Duration::from_secs(1));
for i in 1..=3 {
interval.next().await;
println!("周期性触发 {}", i);
}
// 示例3:取消定时器
println!("\n--- 取消定时器示例 ---");
let cancel_timer = Oneshot::new(Duration::from_secs(3));
let cancel_handle = tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(1)).await;
println!("尝试取消定时器...");
cancel_timer.cancel();
});
match cancel_timer.await {
Ok(()) => println!("定时器正常完成"),
Err(_) => println!("定时器已被取消"),
}
cancel_handle.await.unwrap();
// 示例4:动态调整定时器
println!("\n--- 动态调整定时器示例 ---");
let mut dynamic_interval = Interval::new(Duration::from_millis(500));
for i in 1..=6 {
dynamic_interval.next().await;
println!("动态触发 {}", i);
if i == 3 {
dynamic_interval.set_period(Duration::from_secs(1));
println!("已将间隔调整为1秒");
}
}
// 示例5:与select!宏配合使用
println!("\n--- select!宏示例 ---");
let timer1 = Oneshot::new(Duration::from_secs(2));
let timer2 = Oneshot::new(Duration::from_secs(3));
tokio::select! {
_ = timer1 => println!("定时器1先触发"),
_ = timer2 => println!("定时器2先触发"),
}
}
性能建议
- 对于大量定时器场景,考虑使用单个定时器任务配合任务队列
- 避免创建非常短间隔(<10ms)的定时器,这可能导致不精确
- 对于高精度需求,考虑平台特定的定时器实现
注意事项
- 定时器精度受系统调度器影响
- 取消定时器后,等待该定时器的所有future都会立即返回错误
- 在多线程环境中使用时,确保正确同步
async-timer
是构建异步定时任务的轻量级解决方案,特别适合需要跨平台支持的Rust异步应用。