Асинхронные рабочие процессы в F#

Я программист C#, но у меня есть вопрос об Async Workflows в F#. Предположим, у меня есть следующий класс в библиотеке классов C#:

class File {
 IAsyncResult BeginReadAll(string fileName, AsyncCallback callback, object state){}
 string EndReadAll(IAsyncResult result){}
}

Насколько я понимаю, в F# для меня возможно создать функцию ReadAllAsync, которую я могу вызывать так:

async {  let! rsp = ReadAllAsync() }

и что он не будет блокировать вызывающий поток, а скорее освободит его в пул потоков, а затем вернет в другой поток, когда операция завершится. Я думаю, что я понимаю, как кодировать это в F# с помощью Async.Primitive, но мой вопрос: могу ли я вызвать эту функцию ReadAllAsync из кода C#? Если да, как мне упаковать код F# в библиотеку классов для доступа из C#?

2 ответа

К счастью, когда прибудет Beta2, базовая библиотека F# будет иметь этот метод в модуле Async:

/// Return three functions that can be used to implement the .NET Asynchronous 
/// Programming Model (APM) for a given asynchronous computation.
/// 
/// The functions should normally be published as members with prefix 'Begin',
/// 'End' and 'Cancel', and can be used within a type definition as follows:
/// <c>
///   let beginAction,endAction,cancelAction = Async.AsBeginEnd computation
///   member x.BeginSomeOperation(callback,state) = beginAction(callback,state)
///   member x.EndSomeOperation(iar) = endAction(iar)
///   member x.CancelSomeOperation(iar) = cancelAction(iar)
/// </c>
///
/// The resulting API will be familiar to programmers in other .NET languages and 
/// is a useful way to publish asynchronous computations in .NET components.
static member AsBeginEnd : computation:Async<'T> ->                     // '
                             // The 'Begin' member
                             (System.AsyncCallback * obj -> System.IAsyncResult) * 
                             // The 'End' member
                             (System.IAsyncResult -> 'T) *              // '
                             // The 'Cancel' member
                             (System.IAsyncResult -> unit)

что облегчит написание вашего асинхронного кода с помощью F#, но затем опубликует его обратно на C# или VB, используя обычный APM.

Вот статья, которая показывает, что именно вы просите:

http://codebetter.com/blogs/matthew.podwysocki/archive/2008/10/15/functional-c-implementing-async-computations-in-c.aspx

Тем не менее, вы в конечном итоге используете синтаксис C# монады. Поскольку LINQ был разработан для запросов, это выглядит немного странно. Кроме того, нет поддержки для try / catch или использования для утилизации.

"ReadAllAsync", который вы получаете от Async.BuildPrimitive, не будет обладать той же магией без правильного синтаксиса монады. Называть его достаточно просто, но настоящая полезность - это возможность его составить.

Вам, наверное, лучше просто использовать стиль C#, к сожалению,

Другие вопросы по тегам