Асинхронные рабочие процессы в F # - PullRequest
4 голосов
/ 30 января 2009

Я программист на 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 ]

2 голосов
/ 23 июля 2009

К счастью, когда выйдет 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.

2 голосов
/ 30 января 2009

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

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 #, к сожалению,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...