简体   繁体   中英

F# and WCF consumption

I created a lib in C# with standard "Add Service Reference" dialog but methods which are implemented in it return void so i can't bind to them in async workflows. I can't use the interface with Begin* End* because every method has different number of parameters so it says "Wrong parameters count" (something like that). So how can I consume WCF services asynchronously(async because it's intended to be used in silverlight where everything is async)?

I am unclear what the stumbling block is, but the process should be

  • have svcutil generate async interfaces (with Begin/End methods)
  • use those methods with FromBeginEnd to convert to async: http://msdn.microsoft.com/en-us/library/ee340508.aspx
  • note that if the method returns void ( unit ) then you'll be using do! rather than let! inside an async workflow

To answer one part of your question: "How do I use FromBeginEnd if the Begin function takes some parameters?"

You can do it through the magic of closures. Here's some examples. As you can see, the extension method takes the parameter, but passes to Async.FromBeginEnd an anonymous function that matches the signature expected by FromBeginEnd . The extra parameter is captured in a closure and passed into the real BeginXyz inside the anonymous function.

You can also use the overload of FromBeginEnd that takes the additional parameters first, and then the pointers to the Begin/End functions last, as I did in the AsyncGetReadStream method below - but when there are multiple overloads of BeginXyz I had trouble getting this to work, so I resorted to using closures for most of them.

open System
open System.Data.Services.Client

type System.Data.Services.Client.DataServiceContext with

    member this.AsyncExecute<'a> (uri:Uri) =
        Async.FromBeginEnd((fun (cb, state) -> this.BeginExecute<'a>(uri, cb, state)), 
                           (fun iar -> this.EndExecute<'a>(iar) :?> QueryOperationResponse<'a>))

    member this.AsyncExecute<'a> (continuation:DataServiceQueryContinuation<'a>) =
        Async.FromBeginEnd((fun (cb, state) -> this.BeginExecute<'a>(continuation, cb, state)), 
                           (fun iar -> this.EndExecute<'a>(iar) :?> QueryOperationResponse<'a>))

    member this.AsyncExecuteBatch ([<ParamArray>] queries : DataServiceRequest[]) =
        Async.FromBeginEnd((fun (cb, state) -> this.BeginExecuteBatch(cb, state, queries)), this.EndExecuteBatch)

    member this.AsyncLoadProperty (entity:obj, propertyName:string) =
        Async.FromBeginEnd((fun (cb, state) -> this.BeginLoadProperty(entity, propertyName, cb, state)), 
                           this.EndLoadProperty)

    member this.AsyncLoadProperty (entity:obj, propertyName:string, continuation:DataServiceQueryContinuation) =
        Async.FromBeginEnd((fun (cb, state) -> this.BeginLoadProperty(entity, propertyName, continuation, cb, state)), 
                           this.EndLoadProperty)

    member this.AsyncLoadProperty (entity:obj, propertyName:string, nextLinkUri:Uri) =
        Async.FromBeginEnd((fun (cb, state) -> this.BeginLoadProperty(entity, propertyName, nextLinkUri, cb, state)), 
                           this.EndLoadProperty)

    member this.AsyncSaveChanges () =
        Async.FromBeginEnd(this.BeginSaveChanges, this.EndSaveChanges)

    member this.AsyncSaveChanges (options:SaveChangesOptions) =
        Async.FromBeginEnd((fun (cb, state) -> this.BeginSaveChanges(options, cb, state)), 
                           this.EndSaveChanges)

    member this.AsyncGetReadStream (entity:obj, args:DataServiceRequestArgs) =
        Async.FromBeginEnd(entity, args, this.BeginGetReadStream, this.EndGetReadStream)


type System.Data.Services.Client.DataServiceQuery with

    member this.AsyncExecute () =
        Async.FromBeginEnd(this.BeginExecute, this.EndExecute)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM