2011-07-25 20 views
10

creé un # biblioteca C que devuelve este tipo de datosReferencing asíncrono F # tipo de datos en C#

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

¿Cómo se accede al tipo FSharpAsync por lo que puedo enumerar a través de la tupla de C# e imprimir el contenido?

+3

Personalmente, no prefiero exponer los tipos de datos FSharp como FSharpAsync en una biblioteca escrita en F #. ¿Podría publicar el código F # para que podamos proponer una mejor manera de exponer la biblioteca Fsharp – Ankur

Respuesta

13

En general, no se recomienda exponer los tipos F # como FSharpAsync en una interfaz pública que será utilizada por los clientes C# (consulte F# component design guidelines). Puede usar Async.StartAsTask (en el lado F #) para exponer la operación como Task<T> que es fácil de usar desde C#.

De hecho, también reemplazaría la tupla por un tipo con nombre (que captura el significado de la estructura de datos). Tuplas se pueden utilizar en C#, pero no son idiomática en 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) } } 

Ahora, para exponer la operación a C#, lo mejor es utilizar un tipo con un método estático sobrecargado. El método inicia la operación como una tarea y una sobrecarga especifica el token de cancelación. La convención de nombres de C# para éstos es agregar Async hasta el final del nombre (que no se solapa con F # que añade Async al frente):

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

Su código C# puede entonces utilizar Work.DoWorkAsync() y el trabajo con la tarea en el estilo habitual de C#. Incluso va a trabajar con el await palabra clave que será (probablemente) que se añade a C# 5.

0

Puede manipularlo a través de los métodos estáticos de FSharpAsync. El async que está recibiendo es probablemente del tipo Async<'T>, que no tiene métodos de instancia.

0

Si nos fijamos en el tipo de retorno FSharpAsync<IEnumerable<Tupel<DateTime,string>>> nos dice que se trata de una operación asincrónica que cuando será ejecutado por los métodos estáticos en FSharpAsync devolverá un IEnumerable<Tupel<DateTime,string>>, entonces este será un caso donde la biblioteca F # crea una operación (la operación asincrónica) que su código C# puede ejecutar, por lo que actúa como una operación diferida que puede ejecutar más tarde después de obtenerlo de la biblioteca F # y cuando ejecuta esta operación perezosa le devuelve un IEnumerable que es una especie de vago en el sentido de que extrae valores de él y al mismo tiempo se generan los valores.

Creo que puede devolver IEnumerable<Tupel<DateTime,string>> de su biblioteca F # y no necesita devolver el funcionamiento de Async. Pero una vez más esto depende de lo que hace su F # biblioteca y cómo se supone que debe generar este IEnumerable

2

Referencia FSharp.Core.dll, entonces:

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

FSharpAsync está en el espacio de nombres Microsoft.FSharp.Control.

FSharpOption está en el espacio de nombres Microsoft.FSharp.Core.

+0

exactamente lo que estaba buscando. ¡Gracias! – Micah

Cuestiones relacionadas