在 F# 中实现返回 Task<T> 的 C# 方法

Implementing C# method returning Task<T> in F#

我在 F# 中创建一个继承自 C# class 的类型,它公开了一个在 C# 中 returns Task<T> 的方法。我正在尝试找出在 F#

中执行此操作的最佳方法

假设我的 C# 看起来像这样:

public class Foo {
    public TextWriter Out { get { return Console.Out; } }

    public virtual Task<SomeEnum> DoStuff() {
        return Task.FromResult(SomeEnum.Foo);
    } 
}

public enum SomeEnum {
    Foo,
    Bar
}

我在 F# 中继承该类型的第一遍如下所示:

type Bar() =
    inherits Foo()

    override this.DoStuff() =
        this.Out.WriteLineAsync("hey from F#") |> ignore

        System.Threading.Task.FromResult(SomeEnum.Bar)

但是 a) 感觉不像是真正的异步 b) 感觉不是 F#。

那么我将如何继承 Foo class 并实现 DoStuff 方法期望 return a Task<T>?

我相信 FSharp 包装任务的方法是使用

var a = Async.AwaitIAsyncResult(somecsharpreturningtask) |> ignore

您可以使用 Async.StartAsTask:

type Bar() =
    inherit Foo()
    override this.DoStuff() =
        async { return SomeEnum.Bar } |> Async.StartAsTask

Async.StartAsTaskAsync<T> 作为输入,并且 returns 一个 Task<T>.

执行异步的 F# 方法是使用 asynchronous workflows. Unfortunately, they don't support awaiting non-generic Tasks。但是使用上述问题的解决方法之一,您的代码可能如下所示:

override this.DoStuff() =
    async {
        do! this.Out.WriteLineAsync("hey from F#") |> Async.AwaitVoidTask
        return SomeEnum.Bar
    } |> Async.StartAsTask