Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Referencing Asynchronous F# datatype from C#

I created a F# library that returns this datatype

FSharpAsync<IEnumerable<Tupel<DateTime,string>>>

How do I access the FSharpAsync type so I can enumerate through the tuple from C# and print out the content?

like image 813
unj2 Avatar asked Jul 25 '11 01:07

unj2


2 Answers

It is generally not recommended to expose F# types such as FSharpAsync in a public interface that will be used by C# clients (see F# component design guidelines). You can use Async.StartAsTask (on the F# side) to expose the operation as a Task<T> that is easy to use from C#.

In fact, I would also replace the tuple with a named type (that captures the meaning of the data structure). Tuples can be used in C#, but they are not idiomatic in C#:

// Assuming you have an operation like this 
let asyncDoWork () : Async<seq<DateTime * string>> = (...)

// Define a named type that explains what the date-string pair means
type Item(created:DateTime, name:string) =
  member x.Created = created
  member x.Name = name

// Create a simple wrapper that wraps values into 'Item' type
let asyncDoWorkItems () = 
  async { let! res = asyncDoWork()
          return seq { for (d, n) in res -> Item(d, n) } }

Now, to expose the operation to C#, the best practice is to use a type with an overloaded static method. The method starts the operation as a task and one overload specifies cancellation token. The C# naming convention for these is to add Async to the end of the name (which doesn't overlap with F# which adds Async to the front):

type Work = 
  static member DoWorkAsync() =
    Async.StartAsTask(asyncDoWorkItems())
  static member DoWorkAsync(cancellationToken) =
    Async.StartAsTask(asyncDoWorkItems(), cancellationToken = cancellationToken)

Your C# code can then use Work.DoWorkAsync() and work with the task in the usual C# style. It will even work with the await keyword that will be (probably) added to C# 5.

like image 145
Tomas Petricek Avatar answered Oct 21 '22 03:10

Tomas Petricek


Reference FSharp.Core.dll, then:

FSharpAsync<IEnumerable<Tupel<DateTime,string>>> async = ...
IEnumerable<Tuple<DateTime, string>> result = FSharpAsync.RunSynchronously(async, timeout: FSharpOption<int>.None, cancellationToken: FSharpOption<CancellationToken>.None);

FSharpAsync is in the Microsoft.FSharp.Control namespace.

FSharpOption is in the Microsoft.FSharp.Core namespace.

like image 20
Mauricio Scheffer Avatar answered Oct 21 '22 05:10

Mauricio Scheffer