What can be done to speed up synchronous WCF calls?

后端 未结 2 1976
半阙折子戏
半阙折子戏 2021-01-19 14:52

My performance measurements of synchronous WCF calls from within a Silverlight application showed I can make 7 calls/s on a localhost connection, which is very slo

2条回答
  •  有刺的猬
    2021-01-19 15:26

    Use async calls and run them in parallel.

    The internet is only so fast. As it is, you send a request, wait for an eternity for (1) the message to reach the server, (2) the server to respond, (3) the response to travel back. (1) and (3) take time; there are things like 'miles to the server' and 'the speed of light' in play, maybe. And then you send the next request and do the same waiting game again. And again. In a loop.

    Hence async calls and parallel requests = win.

    (Hint: if you use F#, async can be very easy, as in the sample below.)

    open System
    open System.Diagnostics 
    open System.ServiceModel 
    
    let binding = new BasicHttpBinding()
    let address = "http://YOURSERVERMACHINENAME:11111/Blah"
    
    #if SERVER
    []
    type IMyContract =
        []
        abstract member Subtract : x:int * y:int -> int
    
    type MyService() =
        interface IMyContract with
            member this.Subtract(x,y) = x-y
    
    let host = new ServiceHost(typeof, new Uri(address))
    host.AddServiceEndpoint(typeof, binding, address) |> ignore
    let smb = new Description.ServiceMetadataBehavior()
    smb.HttpGetEnabled <- true
    host.Description.Behaviors.Add(smb)
    host.Open()
    Console.WriteLine("service is open")
    
    #else
    
    []
    type IMyClientContract =
        []
        abstract member Subtract : x:int * y:int -> int
        []
        abstract member BeginSubtract : x:int * y:int * c:AsyncCallback * o:obj -> IAsyncResult
        abstract member EndSubtract : r:IAsyncResult -> int
    
    let client = ChannelFactory.CreateChannel(binding, new EndpointAddress(address))
    let MAX = 30
    
    let syncSw = Stopwatch.StartNew()
    [1..MAX] |> Seq.iter (fun i -> 
        let r = client.Subtract(i,1)
        Console.WriteLine(r))
    Console.WriteLine("sync took {0}ms", syncSw.ElapsedMilliseconds)
    
    let AsyncSubtract(x,y) = Async.FromBeginEnd(x, y, client.BeginSubtract, client.EndSubtract)
    
    let asyncSw = Stopwatch.StartNew()
    [1..MAX] |> Seq.map (fun i -> async {
        let! r = AsyncSubtract(i,1)
        Console.WriteLine(r)}) 
        |> Async.Parallel |> Async.RunSynchronously |> ignore
    Console.WriteLine("async took {0}ms", asyncSw.ElapsedMilliseconds)
    #endif
    
    Console.WriteLine("press a key to quit")
    Console.ReadKey()
    

提交回复
热议问题