Я создал библиотеку F #, которая возвращает этот тип данных
FSharpAsync<IEnumerable<Tupel<DateTime,string>>>
Как мне получить доступ к типу FSharpAsync
, чтобы я мог перечислять через кортеж из С# и распечатывать содержимое?
Я создал библиотеку F #, которая возвращает этот тип данных
FSharpAsync<IEnumerable<Tupel<DateTime,string>>>
Как мне получить доступ к типу FSharpAsync
, чтобы я мог перечислять через кортеж из С# и распечатывать содержимое?
Как правило, не рекомендуется выставлять типы F #, такие как FSharpAsync
, в публичном интерфейсе, который будет использоваться клиентами С# (см. Руководство по разработке компонентов F #). Вы можете использовать Async.StartAsTask
(со стороны F #), чтобы выставить операцию как Task<T>
, которая проста в использовании из С#.
Фактически, я бы также заменил кортеж на именованный тип (который фиксирует значение структуры данных). Кортежи могут использоваться в С#, но они не являются идиоматическими в С#:
// 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) } }
Теперь, чтобы показать операцию на С#, лучше всего использовать тип с перегруженным статическим методом. Метод запускает операцию как задачу, а одна перегрузка указывает маркер отмены. Соглашение об именах С# для них заключается в добавлении Async
в конец имени (которое не перекрывается с F #, которое добавляет Async
в начало):
type Work =
static member DoWorkAsync() =
Async.StartAsTask(asyncDoWorkItems())
static member DoWorkAsync(cancellationToken) =
Async.StartAsTask(asyncDoWorkItems(), cancellationToken = cancellationToken)
Затем ваш С# -код может использовать Work.DoWorkAsync()
и работать с задачей в обычном стиле С#. Он будет работать даже с ключевым словом await
, который будет (возможно) добавлен в С# 5.
Ссылка FSharp.Core.dll, затем:
FSharpAsync<IEnumerable<Tupel<DateTime,string>>> async = ...
IEnumerable<Tuple<DateTime, string>> result = FSharpAsync.RunSynchronously(async, timeout: FSharpOption<int>.None, cancellationToken: FSharpOption<CancellationToken>.None);
FSharpAsync
находится в пространстве имен Microsoft.FSharp.Control
.
FSharpOption
находится в пространстве имен Microsoft.FSharp.Core
.
Вы можете манипулировать им с помощью статических методов FSharpAsync. async
, который вы получаете, скорее всего имеет тип Async<'T>
, который не имеет методов экземпляра.
Если вы посмотрите на тип возврата FSharpAsync<IEnumerable<Tupel<DateTime,string>>>
, то скажите нам, что это асинхронная операция, когда при выполнении статических методов в FSharpAsync возвращается IEnumerable<Tupel<DateTime,string>>
, так что это становится случаем, когда библиотека F # создает (операция async), которую может выполнить ваш С# -код, поэтому он действует как ленивая операция, которую вы можете выполнить позже после ее получения из библиотеки F #, и когда вы выполняете эту ленивую операцию, она возвращает вам IEnumerable, который сам по себе является ленивым в смысл вы извлекаете из него значения и в то же время генерируют значения.
Я думаю, что вы можете просто вернуть IEnumerable<Tupel<DateTime,string>>
из вашей библиотеки F # и не нужно возвращать операцию Async вообще. Но опять же это зависит от того, что делает ваша библиотека F # и как она должна генерировать этот IEnumerable