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 conte开发者_C百科nt?
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.
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.
You can manipulate it via the static methods of FSharpAsync. The async
you're getting is likely of type Async<'T>
, which has no instance methods.
If you look at the return type FSharpAsync<IEnumerable<Tupel<DateTime,string>>>
this tell us that it is a async operation that when gets executed by the static methods in FSharpAsync will return a IEnumerable<Tupel<DateTime,string>>
, so this becomes a case where the F# library create a operation (the async operation) that your C# code can execute, so it act as lazy operation that you can execute later after getting it from F# library and when you execute this lazy operation it returns you a IEnumerable which it self is sort of lazy in the sense that you pull values from it and at the same times the values are generated.
I think you can just return then IEnumerable<Tupel<DateTime,string>>
from your F# library and doesn't need to return Async operation at all. But again this depends on what your F# library does and how it is supposed to generate this IEnumerable
精彩评论