如何在后台运行工作量?

时间:2018-09-18 22:12:09

标签: parallel-processing rust

我有一个基于循环的GUI应用程序。循环的运行频率可能比每一帧都要高,因此它必须轻巧。有时需要完成繁重的工作。我不确定如何实现。我在想像这样的东西:

adoRS(KickOtherDesc)

Playground link

以上示例基于linked answer's tokio-threadpool example。该示例具有如下数据流:

extern crate tokio; // 0.1.7
extern crate tokio_threadpool; // 0.1.2

use std::{thread, time::Duration};
use tokio::{prelude::*, runtime::Runtime};

fn delay_for(
    seconds: u64
    ) -> impl Future<Item = u64, Error = tokio_threadpool::BlockingError> 
{
    future::poll_fn(move || {
        tokio_threadpool::blocking(|| {
            thread::sleep(Duration::from_secs(seconds));
            seconds
        })
    })
}

fn render_frame(n: i8) {
    println!("rendering frame {}", n);
    thread::sleep(Duration::from_millis(500));
}

fn send_processed_data_to_gui(n: i8) {
    println!("view updated. result of background processing was {}", n);
}

fn main() {
    let mut frame_n = 0;
    let frame_where_some_input_triggers_heavy_work = 2;
    let mut parallel_work: Option<BoxedFuture> = None;
    loop {
        render_frame(frame_n);
        if frame_n == frame_where_some_input_triggers_heavy_work {
            parallel_work = Some(execute_in_background(delay_for(1)));
        }

        // check if there's parallel processing going on
        // and handle result if it's finished
        parallel_work
            .take()
            .map(|parallel_work| {
                if parallel_work.done() {
                    // giving result back to app
                    send_processed_data_to_gui(parallel_work.result())
                }
            });

        frame_n += 1;
        if frame_n == 10 {
            break;
        }
    }
}

fn execute_in_background(work: /* ... */) -> BoxedFuture {
    unimplemented!()
}

该示例与我的案例之间的主要区别在于任务let a = delay_for(3); let b = delay_for(1); let sum = a.join(b).map(|(a, b)| a + b); 触发任务a,并且当b完成时b传递了a的结果并继续工作。它将重复多次。

我觉得我正在尝试以一种不是Rust中惯用的异步编程的方式来实现这一目标。

如何在后台运行该工作负载?还是用上面的代码表述:我如何在b中并行执行Future?如果我的方法确实严重偏离轨道,您能朝正确的方向轻推我吗?

0 个答案:

没有答案