首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么除非等待,异步任务(函数)不能运行?

为什么除非等待,异步任务(函数)不能运行?
EN

Stack Overflow用户
提问于 2021-12-15 01:41:22
回答 1查看 299关注 0票数 1

在Rust中,我发现除非等待,否则在运行时不会调用异步任务或函数(甚至可以说是未来的任务)。在其他语言(如C#或NodeJS )中,可以定义async任务并并发运行它们,因为async任务的目的是提供非阻塞IO。例如:

代码语言:javascript
复制
public Task Run();
public Task ListenToMusic();

public async Task RunAndListenToMusic() {
   Task run = Run(); // the task is already running
   Task listenToMusic = ListenToMusic(); // the task is already running
   await Task.WhenAll(run, listenToMusic); 
}

我使用for循环在Rust中测试了这个机制,这个循环实际上打印出了序列号,并发现它们总是按照顺序执行,这意味着第二个任务是在第一个任务之后运行的。

对于像我这样来自dotnet或Java世界的人来说,这是一种奇怪的行为。实际上是怎么回事,我搜索了,但我需要一个人来解释这一点,更多的细节,更简单。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-15 08:11:33

下面是一些与您的示例等效的锈蚀代码:

代码语言:javascript
复制
use tokio; // 1.14.0

async fn task1() {
    for i in 0..10 {
        println!("Task 1: {}", i);
    }
}

async fn task2() {
    for i in 0..10 {
        println!("Task 2: {}", i);
    }
}

#[tokio::main]
async fn main() {
    let t1 = task1();
    let t2 = task2();
    tokio::join!(t1, t2);
}

游乐场

如果运行此代码,您将注意到它在执行task1之前会执行所有的task2。这是预期的,因为执行是单线程的,所以只要task1不尝试阻塞操作,它就会运行。但是,如果我们添加阻塞操作(这里我使用了sleep,但I/O操作也是如此):

代码语言:javascript
复制
use std::time::Duration;
use tokio; // 1.14.0

async fn task1() {
    for i in 0..10 {
        println!("Task 1: {}", i);
        tokio::time::sleep (Duration::from_millis (1)).await;
    }
}

async fn task2() {
    for i in 0..10 {
        println!("Task 2: {}", i);
        tokio::time::sleep (Duration::from_millis (1)).await;
    }
}

#[tokio::main]
async fn main() {
    let t1 = task1();
    let t2 = task2();
    tokio::join!(t1, t2);
}

游乐场

现在我们看到操作是交织在一起的:当一个任务阻塞时,其他任务就有机会运行,这就是异步编程的全部要点。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70357544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档