本文介绍了为什么调用tokio :: spawn会导致出现恐慌"SpawnError {is_shutdown:true}"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想稍后使用Delay做一些工作.如果我使用tokio::run,它就可以正常工作,但是在使用tokio::spawn时,它会死机:

I want to use Delay to do some work later. If I use tokio::run, it just works fine, but it panics when using 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.如何更改代码以使其正常工作?

I need to use spawn not run if I want various tasks to work concurrently. How to change the code to make it work?

推荐答案

tokio::spawn 状态:

有效地,这意味着tokio::spawn仅应在内部的调用中调用tokio::run.

Effectively, this means that tokio::spawn should only be called from inside a call to tokio::run.

由于您只有一个未来要执行,因此不妨直接将其传递给tokio::run.如果您有多个期货,则可以利用 构造一个延迟评估的未来,当它最终运行时将调用spawn:

Since you have only a single future to execute, you might as well just pass it directly to tokio::run. If you had multiple futures, then you can make make use of future::lazy to construct a lazily-evaluated future that will call spawn when it eventually runs:

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的调用首先发生,从而导致相同的事件序列.

Note that if you forget the futures::lazy then you will get the same error. This is because the arguments to functions are evaluated eagerly, which means that the call to tokio::spawn happens first, causing the same sequence of events.

use std::sync::mpsc;

我认为您是否想使用标准库通道是非常值得怀疑的,因为它们不支持异步,因此会阻塞,这在异步代码中是很不好的事情.

I think it's highly doubtful that you want to use the standard libraries channels, as they are not async-aware and thus will block — a very bad thing in async code.

相反,您可能需要 futures::sync::mpsc .

Instead, you probably want futures::sync::mpsc.

这篇关于为什么调用tokio :: spawn会导致出现恐慌"SpawnError {is_shutdown:true}"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 02:07