f# - 此表达式应具有 Async<'a> 类型,但此处具有类型 DispatcherOperation

标签 f# async-await

我正在构建一个包含 F# 文件的项目,在构建过程中,第 39 行出现错误:

This expression was expected to have type Async<'a> but here has type DispatcherOperation


open System
open System.Collections.Generic
open System.Collections.ObjectModel
open System.Linq
open System.Net
open System.Reactive.Disposables
open System.Runtime.CompilerServices
open System.Threading
open System.Windows
open System.Windows.Threading

open Microsoft.Practices.Unity

type IActivityContext<'TResult> = interface
    abstract container: IUnityContainer
    abstract Success: result:'TResult -> unit
    abstract Error: error:Exception -> unit
    abstract Cancel: unit -> unit
    abstract RegisterCancellationCallback: callback:Action->IDisposable
end

[<Extension>]
type ActivityExtensions private() = class
    [<Extension>]
    static member StartViewActivity<'TResult>(container: IUnityContainer, callback: Action<IActivityContext<'TResult>>)= async{
        let! ct = Async.CancellationToken
        return! Async.FromContinuations(fun (success, error, cancel) ->
            let context = {
                new IActivityContext<'TResult> with
                    member this.container = container
                    member this.Success(result:'TResult) = success(result)
                    member this.Error(err:Exception) = error(err)
                    member this.Cancel() = cancel(new OperationCanceledException())
                    member this.RegisterCancellationCallback(callback: Action) = 
                        ct.Register(callback) :> IDisposable
            }
            let disp = Application.Current.Dispatcher
            Async.StartWithContinuations(
(* ERROR -> *)  disp.InvokeAsync((fun() -> callback.Invoke(context))),
                (fun()->()), 
                error, 
                cancel,
                ct
            )
        )
    }
end

有谁知道为什么会出现此错误以及解决方案是什么?

最佳答案

错误消息说明了一切: Dispatcher.InvokeAsync 返回 DispatcherOperation Async.StartWithContinuations期待 Async .

您可以等待 DispatcherOperation.Task :

Async.StartWithContinuations(
    disp.InvokeAsync((fun() -> callback.Invoke(context))).Task |> Async.AwaitTask,
    ignore,
    error,
    cancel,
    ct)

请注意,用 async 包装表达式不会自动使其异步,并且在不等待两次的情况下包装已经异步的流甚至可能根本不会执行内部异步:
let print = async { printfn "Can we observe this?" }

async { return print } |> Async.RunSynchronously // nothing printed
async { return! print } |> Async.RunSynchronously // prints message

所以这不是异步的:
Async.StartWithContinuations(
    async { disp.Invoke((fun() -> callback.Invoke(context))) },
    ignore,
    error,
    cancel,
    ct)

这甚至可能不会调用回调(取决于 InvokeAsync 实现,Task 通常是隐式启动的):
Async.StartWithContinuations(
    async { disp.InvokeAsync((fun() -> callback.Invoke(context))) },
    ignore, 
    error, 
    cancel,
    ct)

最重要的是,回调(通常是成功的,这里: ignore )可能会在内部回调返回之前被调用。

关于f# - 此表达式应具有 Async<'a> 类型,但此处具有类型 DispatcherOperation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41259784/

相关文章:

types - 约束字符串值的类型

f# - 将 COM DLL 与 FSI 结合使用

node.js - 当我与 Puppeteer(集群)交互时关闭页面

c# - 使用 Async 和 Await 转换普通的 Http Post Web 请求

F# 电源问题,它接受两个参数都是 bigint

list - 在 F# 中声明类型列表参数

f# - 为什么 F# Set 需要 IComparable?

javascript - 异步/等待在我的示例中不起作用

c# - C# 中是否存在异步正则表达式,它们对我的情况有帮助吗?

javascript - 异步函数返回一个 promise 数组,而不是实际的值数组