如何在后台运行 F# 中的阻塞调用?

mam*_*mcx 6 f# asynchronous background-process

我需要在后台调用一个调用 web 服务的 API。我不想将(非常复杂的)方法转换为异步,只需说“在后台执行所有这些操作”。

但是我不知道如何使用 F# 来做到这一点。这就是我所拥有的:

            let task = async {
                let result = SyncApi.syncData(login.url, login.zone, login.user, login.pwd) <-- THIS MUST RUN IN BACKGROUND...
                match result with
                |Some(msg) -> failwith msg
                | None -> ()
            }

            task
            |> Async.Catch
            |> Async.RunSynchronously
            |> fun x -> 
                  match x with
                  | Choice1Of2 x -> rootPage.Navigation.PopToRootAsync(true) |> ignore
                  | Choice2Of2 ex -> showMsgError(ex.Message)
Run Code Online (Sandbox Code Playgroud)

Hon*_*tan 6

如果您正在寻找简单的 fire 并且忘记样式来启动 API 调用并且不要在当前线程上使用结果,Async.Start(task)那么这可能就是您要寻找的。它接受Async工作流,在线程池上启动它并立即返回,以便您的方法可以继续。

但是看到您需要结果来更改导航或显示错误消息,您可能需要SyncApi在当前线程上同步调用并等待其结果。

或者,如果您的应用程序模型允许,您可以执行以下操作:

(* Define the task including error handling. *)
let task = async {
    let result = SyncApi.syncData(login.url, login.zone, login.user, login.pwd)
    match result with
    | Some msg ->
        (* This may have to be posted back to the UI context.
           Correct way depends on technology (Xamarin vs. WPF vs. MVC...) *)
        showMsgError msg
    | None -> ()
}

(* Fire and forget the async API call. *)
Async.Start(task)

(* Optimistically navigate away immediately,
   while `task` may still be in progress. *)
rootPage.Navigation.PopToRootAsync(true) |> ignore
Run Code Online (Sandbox Code Playgroud)

这将在线程池上启动任务,导航离开,但如果异步任务失败,它将触发错误消息。但是,它假定您的应用程序可以异步显示错误消息,例如作为弹出窗口,而不仅仅是在启动任务的页面上下文中。