WCF回调特殊使用技巧分享

微软公司研发的一款基于通信方面的开发框架WCF,是一款功能非常强大的开发工具。使用技巧也非常多。其中,异步调用的时候可以使用WCF回调方法来解决。#t#

我在网上收集了许多资料,现在分享一下吧。合理地利用服务的异步调用,可以有效地提高系统性能,合理分配任务的执行。

特别对于UI应用程序而言,可以提高UI的响应速度,改善用户体验。在我编写的应用程序中,下载的文件如果很大,就有必要采用异步方式。对于异步调用的完成,虽然WCF提供了诸如阻塞、等待和轮询等机制,但最好的方式还是使用回调。

也就是利用Begin方法参数中的AsyncCallback对象。这是一个委托对象,它的定义如下所示:

public delegate void AsyncCallback(IAsyncResult ar);

利用异步方式执行服务操作,使得服务在执行过程中不会阻塞主线程,当方法执行完成后,通过AsyncCallback回调对应的方法,可以通知客户端服务执行完毕。例如:

 
 
 
  1. //Invoke it Asynchronously   
  2. m_service.BeginTransferDocument
    (m_doc,OnTransferCompleted,null);   
  3. //Do some work;   
  4. //callback method   
  5. void OnTransferCompleted
    (IAsyncResult result)   
  6. {   
  7. Stream stream = m_service.
    EndTransferDocument(result);   
  8. result.AsyncWaitHandle.Close();   
  9. lbMessage.Text = string.Format
    ("The file {0} had been transfered
     sucessfully.",   
  10. m_doc.FileName);   
  11. }  

在调用BeginTransferDocument()方法之后,主线程不会被阻塞,仍然可以继续执行其它工作。而当服务方法执行完毕之后,会自动调用WCF回调方法,执行方法中的内容。

上述实现存在一个问题,就是对于lbMessage控件的操作。由于WCF回调方法并非运行在主线程中,如果回调方法需要更新与异步调用结果相关的界面,例如本例中的lbMessage控件,则需要将回调的调用封送(Marshal)到当前主程序界面的同步上下文中。我们可以使用 SynchronizationContext以及它的SendOrPostCallback委托,对调用进行封送:

 
 
 
  1. public 
  2. ExplorerClientForm()
  3. InitializeComponent();
  4.  m_synchronizationContext = 
    SynchronizationContext.Current; 
  5. private SynchronizationContext 
    m_synchronizationContext;   

则WCF回调方法修改为:

 
 
 
  1. //callback 
  2. method void OnTransferCompleted
    (IAsyncResult result) 
  3. Stream stream = m_service.EndTrans
    ferDocument(result); 
  4. result.AsyncWaitHandle.Close(); 
  5. SendOrPostCallback 
  6. callback = delegate 
  7. lbMessage.Text = string.Format
    ("The file {0} had been transfered 
    sucessfully.", m_doc.FileName);
  8.  };
  9.  m_synchronizationContext.Send
    (callback,null);  

 

THE END