Skip to content

Conversation

@igiona
Copy link
Contributor

@igiona igiona commented Jan 11, 2026

Lately I found myself dealing with large file dumps from my application.
The file-dump is triggered in a button callback, from within the slint event-loop.
I didn't want to build the "infrastructure" to pass my request to a tokio thread, there use the async file-syetem acceess and then go back to the slint event-loop with the action results.
I find that for this kind of operation, it's really practical to be able to:

main_window.on_export_data(move || {
            slint::spawn_local(async move {
                // This future will be executed in the slint-event loop

                let handle = slint::spawn_blocking(move || {
                    // This closure will be execute in a new std::thread
                    export_big_data()
                });

                match handle.await.expect("Spawn blocking should work") {
                    Ok(_) => info!("File exported successfully"),                    
                    Err(e) => error!("File export error: {e}"),
                }
            })
            .expect("Local spawn should work");
        })

Therefore, I added the possibility to run a blocking code into a newly spawned thread, allowing to .await it's completion from within the slint event-loop (in a spawn_local future).
This allows blocking operations (like large filesystem dump that for a reason or another aren't async) to not block the GUI while still being able to be awaited for proper results and error handling.

NOTE: I'm pretty sure that the code can't be merged as is due to lack of documentation and probably also the fact that this code has the chance to land in another module. Additionally, I'm not sure about the potential restrictions on using std::sync::mutex for example.
I placed the code there, where it seemed more appropriate (I took spawn_local as example), but since I'm not super familiar with the code base it might still be wrong.
I'm seeking for advice on how to polish this up, and also of course if you see issues or better alternatives to this approach.

@tronical
Copy link
Member

I guess this is where we're bordering with full async run-times. My feeling is that perhaps it's better to use a runtime's function such as https://docs.rs/smol/latest/smol/fn.unblock.html that implements thread-pooling, i.e. imposes an upper limit. OTOH I see the appeal of a simple solution inside Slint. Let's see what Olivier's take here is.

@igiona
Copy link
Contributor Author

igiona commented Jan 12, 2026

I guess this is where we're bordering with full async run-times. My feeling is that perhaps it's better to use a runtime's function such as https://docs.rs/smol/latest/smol/fn.unblock.html that implements thread-pooling, i.e. imposes an upper limit. OTOH I see the appeal of a simple solution inside Slint. Let's see what Olivier's take here is.

I see your point.
The problem with some runtimes (i.e. tokio) is that they are very opinionated on where its APIs (e.g. tokio::task::spawn_bloking) must be executed and therefore won't allow most of the calls from outside the tokio-context (and the slint event-loop will never be in that context).
Pulling another executor/dep like smol sounds a bit overkill but might be an option.

@ogoffart
Copy link
Member

Thanks a lot for the PR and for explaining the motivation so clearly.

I do not think this belongs in Slint itself. The functionality added here is not Slint specific. It is a general helper that can live in a separate crate, or some async helper crate

Slint should stay focused on the UI and its own event loop.

If anything, we could try to document how to use some other specific async runtime or other crate and how they play with Slint.

@ogoffart
Copy link
Member

ogoffart commented Jan 21, 2026

I'm going to close this PR because we think it doesn't belong in Slint.

You could make it a standalone crate or as part of a bigger crate.
I found https://docs.rs/async-thread/latest/async_thread/
and rust-lang/rust#131389

@ogoffart ogoffart closed this Jan 21, 2026
@igiona
Copy link
Contributor Author

igiona commented Jan 21, 2026

@ogoffart thanks for the feedback, and apologize for the delay, I have been pretty sick since a week.

I was going to ask if you had such crate in mind, but you already answered ;)

@igiona igiona deleted the add-spawn-blocking branch January 21, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants