6

I'm creating a type in F# that inherits from a C# class that exposes a method that returns Task<T> in C#. I'm trying to work out what'd be the best way to do that in F#

Say my C# looks like this:

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
}

My first pass of inheriting that type in F# looks like so:

type Bar() =
    inherits Foo()

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

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

But a) it doesn't feel like it's actually async and b) it just feels not-F#.

So how would I go about inheriting the Foo class and implement the DoStuff method that expects to return a Task<T>?

5
  • 1
    Is your actual method really just returning a constant? Because it doesn't make sense to do that in a way that's "actually async". If that is the case, Task.FromResult() is the right solution both in C# and F#. Commented Jun 12, 2015 at 1:59
  • We can assume that the value to be returned will be based off some logic. Commented Jun 12, 2015 at 2:16
  • But is that logic doing any inherently asynchronous work (e.g. accessing the file system or the network)? Or could it take relatively long time (say, more than 50 ms)? Commented Jun 12, 2015 at 2:21
  • Yep, file system, network, db, etc could be the async stuff that is done here. The base class also does expose a TextWriter to write to the output stream (console, network stream, etc) which is why I used it in my example there. Commented Jun 12, 2015 at 3:44
  • [slightly] Related: stackoverflow.com/questions/25605130/… Commented Jun 12, 2015 at 9:06

3 Answers 3

13

You can use Async.StartAsTask:

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

Async.StartAsTask takes Async<T> as input, and returns a Task<T>.

Sign up to request clarification or add additional context in comments.

Comments

2

The F# way of doing async is using asynchronous workflows. Unfortunately, they don't support awaiting non-generic Tasks. But using one of the workarounds from the above question, your code could look like this:

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

Comments

-1

I believe the FSharp way of wrapping over tasks is to use

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.