tenho seguinte código tauri v2 rust

async fn download_file(
    app_handle: &AppHandle,
    client: &Client,
    entry: PatchEntry,
    download_dir: &Path,
    current_file: usize,
    total_files: usize,
) -> Result<(), Box<dyn std::error::Error>> {
    let url = format!("https://hil-speed.hetzner.com/{}", entry.file_name);
    let file_path = download_dir.join(&entry.file_name);

    let mut response = client.get(&url).send().await?;
    let total_bytes = response.content_length().unwrap_or(0);
    let mut file = tokio_fs::OpenOptions::new()
        .write(true)
        .create(true)
        .open(file_path)
        .await?;

    let mut downloaded_bytes = 0;
    let start_time = Instant::now();

    while let Some(chunk) = response.chunk().await? {
        file.write_all(&chunk).await?;
        downloaded_bytes += chunk.len() as u64;

        let elapsed_time = Instant::now().duration_since(start_time).as_secs_f64();
        let speed = if elapsed_time > 0.0 {
            downloaded_bytes as f64 / elapsed_time
        } else {
            0.0
        };

        app_handle.emit("download_message", DownloadMessage { message: "Baixando".to_string() })?;
        app_handle.emit("download_info", DownloadInfo {
            current_file,
            total_files,
            file_name: entry.file_name.clone(),
            downloaded_bytes,
            total_bytes,
        })?;
        app_handle.emit("download_speed", speed)?;
    }

    app_handle.emit("download_message", DownloadMessage { message: "Download concluído".to_string() })?;
    Ok(())
}

async fn check_server_connection(client: &Client, url: &str) -> Result<(), Box<dyn std::error::Error>> {
    let response = client.get(url).send().await?;
    if response.status().is_success() {
        Ok(())
    } else {
        Err("Failed to connect to the server".into())
    }
}

#[tauri::command]
pub async fn start_downloads(app_handle: AppHandle) -> Result<(), String> {
    let exe_dir = get_exe_dir();
    let patch_file_path = exe_dir.join("patch.json");
    let download_dir = exe_dir.join("patchs");

    if !download_dir.exists() {
        tokio_fs::create_dir_all(&download_dir).await.map_err(|e| e.to_string())?;
    }

    let patches = read_patch_file(&patch_file_path).await.map_err(|e| e.to_string())?;
    let client = Client::new();
    let total_files = patches.len();

    app_handle.emit("download_message", DownloadMessage {
        message: "Conectando ao servidor...".to_string(),
    }).map_err(|e| e.to_string())?;

    let server_url = "https://hil-speed.hetzner.com/";
    if let Err(err) = check_server_connection(&client, server_url).await {
        app_handle.emit("download_message", DownloadMessage {
            message: format!("Erro ao conectar ao servidor: {}", err),
        }).map_err(|e| e.to_string())?;
        return Err(format!("Erro ao conectar ao servidor: {}", err));
    }

    app_handle.emit("download_message", DownloadMessage {
        message: "Conexão estabelecida com sucesso. Iniciando download...".to_string(),
    }).map_err(|e| e.to_string())?;

    // Executando downloads sequencialmente
    for (current_file, entry) in patches.into_iter().enumerate() {
        let current_file = current_file + 1;
        if let Err(err) = download_file(&app_handle, &client, entry, &download_dir, current_file, total_files).await {
            app_handle.emit("download_message", DownloadMessage {
                message: format!("Erro ao baixar arquivo: {}", err),
            }).map_err(|e| e.to_string())?;
        }
    }

    Ok(())
}

download_file está gerando um pequeno travento da ui do app, tem como executar ele em um thread separado ?