我编写了以下WCF服务,它实现了两种方法。它们都做同样的事情,但其中一个是同步的,另一个是异步的。负载测试的结果(使用Pylot)令人失望。我从方法的同步和异步版本获得几乎相同的吞吐量(参见下面的性能数字)。
我在真正的IIS站点(而不是Cassini)中部署了该服务,我看到了相同的模式。我究竟做错了什么?我的印象是使用WCF AsyncPattern我可以增加负载。我的假设是否正确?我做错了吗?
谢谢!
[ServiceContract]
public class Service1
{
// Synchronous version
[WebGet(UriTemplate = "/sync")]
public List<SampleItem> GetSamples()
{
return this.LongRunningMethod();
}
// Asynchronous version - Begin
[WebGet(UriTemplate = "/async")]
[OperationContract(AsyncPattern = true)]
public IAsyncResult BeginGetSampleAsync(AsyncCallback callback, object state)
{
var task = Task<List<SampleItem>>.Factory.StartNew(() => this.LongRunningMethod());
Func<List<SampleItem>> getSampleItems = () => this.LongRunningMethod();
return getSampleItems.BeginInvoke(callback, state);
}
// Asynchronous version - End
public List<SampleItem> EndGetSampleAsync(IAsyncResult result)
{
AsyncResult typedAsyncResult = (AsyncResult)result;
Func<List<SampleItem>> func = (Func<List<SampleItem>>)typedAsyncResult.AsyncDelegate;
return func.EndInvoke(result);
}
private List<SampleItem> LongRunningMethod()
{
// Simulate some load... I/O operations
Thread.Sleep(500);
return new List<SampleItem>() { new SampleItem() { Id = 1, StringValue = "Hello" } };
}
以下是性能。号。
Performance Numbers
-------------------------------------------------
Test parameters:
number of agents: 500
test duration in seconds: 60
rampup in seconds: 0
interval in milliseconds: 0
test case xml: **syncTestCase.xml**
log messages: False
Started agent 500
All agents running...
[################100%##################] 60s/60s
Requests: 3836
Errors: 0
Avg Response Time: 7.286
Avg Throughput: 63.92
Current Throughput: 70
Bytes Received: 852036
-------------------------------------------------
Test parameters:
number of agents: 500
test duration in seconds: 60
rampup in seconds: 0
interval in milliseconds: 0
test case xml: **asyncTestCase.xml**
log messages: False
Started agent 500
All agents running...
[################100%##################] 60s/60s
Requests: 3884
Errors: 0
Avg Response Time: 7.176
Avg Throughput: 64.66
Current Throughput: 620
Bytes Received: 862248
-------------------------------------------------
答案 0 :(得分:3)
你的测试非常人为。异步编程最适用于 I / O绑定操作,它不需要等待正在运行的线程(相反,它们应基于IO-completion ports或类似)。您的测试使用线程池线程(BeginInvoke
/ EndInvoke
)并阻止它们(Thread.Sleep
),这几乎可以保证您最终会比同步中的更糟你不吃任何额外线程的情况。
简而言之:除非您在服务器端进行I / O绑定工作,否则不要使用服务器端异步 - 如果您受CPU限制,请坚持同步服务器实现(可能与{结合使用} {3}}设置等于服务器上的CPU核心数。)