WCF回調(diào)特殊使用技巧分享
微軟公司研發(fā)的一款基于通信方面的開發(fā)框架WCF,是一款功能非常強大的開發(fā)工具。使用技巧也非常多。其中,異步調(diào)用的時候可以使用WCF回調(diào)方法來解決。#t#
我在網(wǎng)上收集了許多資料,現(xiàn)在分享一下吧。合理地利用服務(wù)的異步調(diào)用,可以有效地提高系統(tǒng)性能,合理分配任務(wù)的執(zhí)行。
特別對于UI應(yīng)用程序而言,可以提高UI的響應(yīng)速度,改善用戶體驗。在我編寫的應(yīng)用程序中,下載的文件如果很大,就有必要采用異步方式。對于異步調(diào)用的完成,雖然WCF提供了諸如阻塞、等待和輪詢等機制,但最好的方式還是使用回調(diào)。
也就是利用Begin方法參數(shù)中的AsyncCallback對象。這是一個委托對象,它的定義如下所示:
public delegate void AsyncCallback(IAsyncResult ar);
利用異步方式執(zhí)行服務(wù)操作,使得服務(wù)在執(zhí)行過程中不會阻塞主線程,當(dāng)方法執(zhí)行完成后,通過AsyncCallback回調(diào)對應(yīng)的方法,可以通知客戶端服務(wù)執(zhí)行完畢。例如:
- //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);
- }
在調(diào)用BeginTransferDocument()方法之后,主線程不會被阻塞,仍然可以繼續(xù)執(zhí)行其它工作。而當(dāng)服務(wù)方法執(zhí)行完畢之后,會自動調(diào)用WCF回調(diào)方法,執(zhí)行方法中的內(nèi)容。
上述實現(xiàn)存在一個問題,就是對于lbMessage控件的操作。由于WCF回調(diào)方法并非運行在主線程中,如果回調(diào)方法需要更新與異步調(diào)用結(jié)果相關(guān)的界面,例如本例中的lbMessage控件,則需要將回調(diào)的調(diào)用封送(Marshal)到當(dāng)前主程序界面的同步上下文中。我們可以使用 SynchronizationContext以及它的SendOrPostCallback委托,對調(diào)用進行封送:
- public
- ExplorerClientForm(){
- InitializeComponent();
- m_synchronizationContext =
SynchronizationContext.Current;- }
- private SynchronizationContext
m_synchronizationContext;
則WCF回調(diào)方法修改為:
- //callback
- method void OnTransferCompleted
(IAsyncResult result)- {
- Stream stream = m_service.EndTrans
ferDocument(result);- result.AsyncWaitHandle.Close();
- SendOrPostCallback
- callback = delegate
- {
- lbMessage.Text = string.Format
("The file {0} had been transfered
sucessfully.", m_doc.FileName);- };
- m_synchronizationContext.Send
(callback,null);