我在Silverlight应用程序中对同步WCF调用的性能测量表明,我可以在localhost连接上进行 7次调用,非常慢。这可以加速,还是这是正常的?
这是我的测试代码:
const UInt32 nrCalls = 100;
ICalculator calculator = new CalculatorClient(); // took over from the MSDN calculator example
for (double i = 0; i < nrCalls; ++i)
{
var call = calculator.BeginSubtract(i + 1, 1, null, null);
call.AsyncWaitHandle.WaitOne();
double result = calculator.EndSubtract(call);
}
说明:
更新:我已将客户端从Silverlight移植到.NET,这解决了性能问题。在该测试中,同步呼叫在 140个呼叫/ s (而不是7个呼叫/秒)进行,异步呼叫以200个呼叫/秒(而不是16个呼叫/秒)进行。显然, Silverlight平台固有的缓慢。我必须学会忍受它。
答案 0 :(得分:4)
不是很多。你运行100个http调用的问题,这需要时间。你不是每次都要通过生成一个新客户来吹嘘....所以,对不起。
一般来说,这是一个不好的例子(或者是一个表现不好的好习惯)。服务应始终粗粒度以避免呼叫开销。一般来说,服务应该具有一定的“权重”。
计算器可以接受一系列操作,因此所有100次计算都可以一次发送,例如。
在设计自己的界面时请记住这一点。
答案 1 :(得分:1)
使用异步调用并并行运行它们。
互联网速度如此之快。实际上,您发送请求,等待永恒(1)消息到达服务器,(2)服务器响应,(3)回复的响应。 (1)和(3)需要时间;也许,有些东西比如“服务器里程”和“光速”。然后你发送下一个请求并再次进行相同的等待游戏。然后再次。在循环中。
因此异步调用和并行请求= win。
(提示:如果使用F#,异步可以非常简单,如下面的示例所示。)
open System
open System.Diagnostics
open System.ServiceModel
let binding = new BasicHttpBinding()
let address = "http://YOURSERVERMACHINENAME:11111/Blah"
#if SERVER
[<ServiceContract>]
type IMyContract =
[<OperationContract>]
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<MyService>, new Uri(address))
host.AddServiceEndpoint(typeof<IMyContract>, binding, address) |> ignore
let smb = new Description.ServiceMetadataBehavior()
smb.HttpGetEnabled <- true
host.Description.Behaviors.Add(smb)
host.Open()
Console.WriteLine("service is open")
#else
[<ServiceContract(Name="IMyContract")>]
type IMyClientContract =
[<OperationContract>]
abstract member Subtract : x:int * y:int -> int
[<OperationContract(AsyncPattern=true)>]
abstract member BeginSubtract : x:int * y:int * c:AsyncCallback * o:obj -> IAsyncResult
abstract member EndSubtract : r:IAsyncResult -> int
let client = ChannelFactory<IMyClientContract>.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()