F # и расход WCF - PullRequest
       34

F # и расход WCF

2 голосов
/ 26 февраля 2011

Я создал lib в C # со стандартным диалогом «Add Service Reference», но реализованные в нем методы возвращают void, поэтому я не могу связываться с ними в асинхронных рабочих процессах.Я не могу использовать интерфейс с Begin * End *, потому что у каждого метода есть разное количество параметров, поэтому он говорит «Неверный счетчик параметров» (что-то в этом роде).Итак, как я могу использовать службы WCF асинхронно (асинхронно, потому что оно предназначено для использования в Silverlight, где все асинхронно)?

Ответы [ 2 ]

3 голосов
/ 26 февраля 2011

Мне неясно, что является камнем преткновения, но процесс должен быть

  • иметь svcutil генерировать асинхронные интерфейсы (с методами Begin / End)
  • использовать эти методы с FromBeginEnd для преобразования в асинхронное: http://msdn.microsoft.com/en-us/library/ee340508.aspx
  • обратите внимание, что если метод возвращает void (unit), то вы будете использовать do! вместо let! внутри асинхронного рабочего процесса
2 голосов
/ 26 февраля 2011

Чтобы ответить на одну часть вашего вопроса: «Как использовать FromBeginEnd, если функция Begin принимает некоторые параметры?»

Вы можете сделать это с помощью магии замыканий.Вот несколько примеров.Как видите, метод расширения принимает параметр, но передает Async.FromBeginEnd анонимную функцию, которая соответствует сигнатуре, ожидаемой FromBeginEnd.Дополнительный параметр записывается в замыкание и передается в действительную BeginXyz внутри анонимной функции.

Вы также можете использовать перегрузку FromBeginEnd, которая сначала берет дополнительные параметры, а затем указатели наФункции Begin / End выполняются последними, как я это делал в методе AsyncGetReadStream ниже, но при множественных перегрузках BeginXyz у меня возникли проблемы с выполнением этого, поэтому я прибегнул к использованию замыканий для большинства из них.

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)
...