Ответ 1
Как правило, не рекомендуется выставлять типы 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.