我正在构建一个包含 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/