Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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>?

like image 628
Aaron Powell Avatar asked Jun 12 '15 00:06

Aaron Powell


People also ask

What is implementing in C?

Basically, an implementation is the combination of a compiler and the C library it supports. – Jonathan Leffler. Apr 15, 2019 at 14:20. 4. C language = what you type into a text editor; implementation = the thing that actually does something with what you typed.

How was C implemented?

The origin of C is closely tied to the development of the Unix operating system, originally implemented in assembly language on a PDP-7 by Dennis Ritchie and Ken Thompson, incorporating several ideas from colleagues. Eventually, they decided to port the operating system to a PDP-11.

Can we implement classes in C?

This document describes the simplest possible coding style for making classes in C. It will describe constructors, instance variables, instance methods, class variables, class methods, inheritance, polymorphism, namespaces with aliasing and put it all together in an example project.


2 Answers

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>.

like image 79
Mark Seemann Avatar answered Nov 08 '22 21:11

Mark Seemann


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
like image 28
svick Avatar answered Nov 08 '22 19:11

svick