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

6

我正在创建一个类型的 F#,该类型继承自一个 C# 类,该类公开了一个在 C# 中返回 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 类并实现期望返回 Task<T>DoStuff 方法呢?


1
你实际的方法只是返回一个常量吗?因为以“实际异步”的方式这样做是没有意义的。如果是这种情况,Task.FromResult()在C#和F#中都是正确的解决方案。 - svick
我们可以假设返回的值将基于某些逻辑。 - Aaron Powell
但是这个逻辑是否在进行任何本质上的异步工作(例如访问文件系统或网络)?或者它可能需要相对较长的时间(比如超过50毫秒)? - svick
是的,文件系统、网络、数据库等都可以在这里完成异步操作。基类还公开了一个 TextWriter 以便写入输出流(控制台、网络流等),这也是我在示例中使用它的原因。 - Aaron Powell
相关内容:https://dev59.com/t4Lba4cB1Zd3GeqPmP7q - Ruben Bartelink
3个回答

13
你可以使用 Async.StartAsTask:
type Bar() =
    inherit Foo()
    override this.DoStuff() =
        async { return SomeEnum.Bar } |> Async.StartAsTask

Async.StartAsTask需要以Async<T>为输入,并返回Task<T>


2
F#实现异步的方式是使用异步工作流。不幸的是,它们不支持等待非泛型Task。但是,使用上面问题中的其中一种解决方法,你的代码可能会像这样:
override this.DoStuff() =
    async {
        do! this.Out.WriteLineAsync("hey from F#") |> Async.AwaitVoidTask
        return SomeEnum.Bar
    } |> Async.StartAsTask

-1

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接