Question

I have following C# async interface:

x.BeginOperation(a:sting, b:string, c:string, d:string, g:string, ?q:string) : IAsyncResult
x.EndOperation(result:IAsyncResult) : IEnumerable<string>

I would like to use this in my async workflow and get Async<'T> object that would represent the computation.

I guess that Async.FromBeginEnd is the way to go but I have hard time trying to pass begin/end operation method to it. BeginOperation has too many arguments plus the optional one (plus I don't really manage to wrap my mind around the AsyncCallback * obj in signature).

What is the proper way to get Async from this interface. Thanks.

Was it helpful?

Solution

Assuming that your interface is declared something like this:

type IMyInterface =
    abstract member BeginOperation :
        (string * string * string * string * string * string option) ->
        IAsyncResult
    abstract member EndOperation : IAsyncResult -> string seq

you should be able to create an Async<'T> using a little helper function like this:

let toAsync (x : IMyInterface) =
    let beginAction (callback, values : obj) =
        match values with
        | :? (string * string * string * string * string * string option) as v ->
            x.BeginOperation v
        | _ -> failwith "Unexpected values"

    Async.FromBeginEnd (beginAction, x.EndOperation)

The inner beginAction helper function has the signature 'a * obj -> IAsyncResult, which means that it takes a tuple of the generic type 'a (in C# it would typically be denoted as T) and a System.Object, and returns an IAsyncResult instance.

For Async.FromBeginEnd, that's the required signature for the beginAction.

The interface's EndOperation method already has the correct signature, so it can be passed in unmodified.

The entire signature of the toAsync function is IMyInterface -> Async<seq<string>>.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top