And*_*sch 8 c# wcf asynchronous
我正在实现一个异步服务.在评估了微软的例子之后,我想知道他们的方法是否真的是异步的.我很确定它是,但我在网上看到的一些样本和AsyncCallback参数让我想知道.
根据示例,我们需要实现Begin和End方法对,如下所示:
public IAsyncResult BeginGetAcmeAnvil(AsyncCallback callback, object state)
{
// Starts synchronous task
var acmeAsyncResult = new AcmeAsyncResult<Anvil>
{
Data = new Anvil()
};
return acmeAsyncResult;
}
public Anvil EndGetAcmeAnvil(IAsyncResult result)
{
var acmeAsyncResult = result as AcmeAsyncResult<Anvil>;
return acmeAsyncResult != null
? acmeAsyncResult.Data
: new Anvil();
}
Run Code Online (Sandbox Code Playgroud)
非常简单,但为什么我们有AsyncCallback参数?我们不应该调用callback哪个将依次触发End方法?
这就是我的想法:
public delegate void AsyncMethodCaller(AcmeAsyncResult<Anvil> acmeAsyncResult,
AsyncCallback callback);
public IAsyncResult BeginGetAcmeAnvil(AsyncCallback callback, object state)
{
var acmeAsyncResult = new AcmeAsyncResult<Anvil>();
var asyncMethodCaller = new AsyncMethodCaller(GetAnvilAsync);
// Starts asynchronous task
asyncMethodCaller.BeginInvoke(acmeAsyncResult, callback, null, null);
return acmeAsyncResult;
}
private void GetAcmeAnvilAsync(AcmeAsyncResult<Anvil> acmeAsyncResult,
AsyncCallback callback)
{
acmeAsyncResult.Data = new Anvil();
callback(acmeAsyncResult); // Triggers EndGetAcmeAnvil
}
public Anvil EndGetAcmeAnvil(IAsyncResult result)
{
var acmeAsyncResult = result as AcmeAsyncResult<Anvil>;
return acmeAsyncResult != null
? acmeAsyncResult.Data
: new Anvil();
}
Run Code Online (Sandbox Code Playgroud)
我使用loadUI进行了一些负载测试,但没有明显的性能变化.
我找到了一篇很好的文章,解释了如何从Async WCF服务中获得最佳性能.
要点是:
以下是文字摘录:
为了获得最佳性能,在调用/实现上述异步模式时,有两个原则:
原则1:不要在Begin方法中做重量级的工作......
这样做的原因是您应该尽快返回调用线程,以便调用者可以安排其他工作.如果它是UI线程,则应用程序需要使用该线程来响应用户输入.如果可能,您应该始终将重要操作放在不同的线程中.
原则2:避免在Begin方法的同一个线程上调用End方法.
的结束方法通常是阻塞.它等待操作完成.如果实现End方法,您会看到它实际上调用了IAsyncResult.WaitHandle.WaitOne().另一方面,作为正常实现,此WaitHandle是一个分配了ManualResetEvent的延迟.只要你不打电话,它根本就不会分配.为了快速操作,这非常便宜.但是,一旦调用End,就必须分配它.调用End的正确位置来自操作的回调.当回调被调用,这意味着阻止工作真正完成.此时,您可以调用End以在不牺牲性能的情况下检索数据.