为什么要求在恐慌TOKIO ::产卵结果“SpawnError {is_shutdown:真正}”?

问题描述 投票:2回答:1

我想用Delay后来做了一些工作。如果我使用tokio::run,它只是正常工作,但它使用tokio::spawn当恐慌:

use std::sync::mpsc;
use std::time::*;

use tokio::prelude::*; // 0.1.14

fn main() {
    let (tx, rx) = mpsc::channel();
    let task = tokio::timer::Delay::new(Instant::now() + Duration::from_secs(1))
        .map(move |_| {
            tx.send(String::from("hello")).unwrap();
            ()
        })
        .map_err(|e| {
            panic!("{:?}", e);
        });
    tokio::spawn(task);
    let msg = rx.recv().unwrap();
    println!("{}", msg);
}
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: SpawnError { is_shutdown: true }', src/libcore/result.rs:1009:5

我需要使用spawn如果我想不同的任务同时工作不run。如何更改代码,使其工作?

rust rust-tokio
1个回答
8
投票

对于tokio::spawn状态的文档:

如果默认执行未设置或者产卵到默认执行返回一个错误,这个功能就会死机。

实际上,这意味着tokio::spawn只能从内部调用tokio::run被调用。

既然你只有一个未来的执行,你可能也只是通过它直接tokio::run。如果你有多个期货,那么你可以让化妆用future::lazy的构建惰性计算的未来,将调用spawn当它最终运行:

use std::time::*;
use tokio::prelude::*; // 0.1.14

fn main() {
    tokio::run(futures::lazy(|| {
        tokio::spawn(wait_one_sec().map(|_| println!("One")));
        tokio::spawn(wait_one_sec().map(|_| println!("Two")));
        Ok(())
    }));
}

fn wait_one_sec() -> impl Future<Item = (), Error = ()> {
    tokio::timer::Delay::new(Instant::now() + Duration::from_secs(1))
        .map(drop)
        .map_err(|e| panic!("{:?}", e))
}

请注意,如果你忘记了futures::lazy那么你会得到同样的错误。这是因为函数的参数都在热切评估,这意味着调用tokio::spawn首先发生,导致相同的事件序列。

use std::sync::mpsc;

我认为这是非常值得怀疑的,要使用标准库的通道,因为它们不是异步感知,从而将阻止 - 在异步代码非常糟糕的事情。

相反,你可能想futures::sync::mpsc

© www.soinside.com 2019 - 2024. All rights reserved.