技术开发 频道

WCF中的异步调用

 
  调用方式如下:
BasicHttpBinding binding = new BasicHttpBinding(); 
binding.SendTimeout = TimeSpan.FromMinutes(10);
binding.TransferMode = TransferMode.Streamed;
binding.MaxReceivedMessageSize = 9223372036854775807;

EndpointAddress address = new EndpointAddress
("http://localhost:8008/DocumentExplorerService");

ChannelFactory<IDocumentsExplorerService> factory =
new ChannelFactory<IDocumentsExplorerService>(binding,address);

m_service = factory.CreateChannel();

……
IAsyncResult result = m_service.BeginTransferDocument(doc,null,null);
result.AsyncWaitHandle.WaitOne();
Stream stream = m_service.EndTransferDocument(result);
   如果采用SvcUtil生成客户端代理文件,可以有更好的方式实现异步,也就是使用SvcUtil的/async开关,例如:
svcutil /async http://localhost:8008/DocumentExplorerService

   唯一不足的是,它会不分青红皂白,为所有服务操作都生成对应的异步方法。这样的做法未免过于武断。

   合理地利用服务的异步调用,可以有效地提高系统性能,合理分配任务的执行。特别对于UI应用程序而言,可以提高UI的响应速度,改善用户体验。在我编写的应用程序中,下载的文件如果很大,就有必要采用异步方式。

   对于异步调用的完成,虽然WCF提供了诸如阻塞、等待和轮询等机制,但最好的方式还是使用回调。也就是利用Begin方法参数中的AsyncCallback对象。这是一个委托对象,它的定义如下所示:
public delegate void AsyncCallback(IAsyncResult ar);
    利用异步方式执行服务操作,使得服务在执行过程中不会阻塞主线程,当方法执行完成后,通过AsyncCallback回调对应的方法,可以通知客户端服务执行完毕。例如:
//Invoke it Asynchronously 
m_service.BeginTransferDocument(m_doc,OnTransferCompleted,null);

//Do some work;


//callback method
void OnTransferCompleted(IAsyncResult result)
{
Stream stream = m_service.EndTransferDocument(result);
result.AsyncWaitHandle.Close();

lbMessage.Text = string.Format("The file {0} had been transfered sucessfully.",
m_doc.FileName);
}

0
相关文章