教你利用WCF回調操作解決死鎖問題
死鎖這個問題是很麻煩的,我們現在就這個問題分析一下,這里提供了方案則是將WCF回調操作設置為單向操作。此時,回調調用不會產生應答消息,服務操作一旦執行了WCF回調操作,就會繼續執行,回調對象不會爭用與服務實例關聯的鎖,從而解決了死鎖問題。
- interface IMyContractCallback
- {
- [OperationContract(IsOneWay = true)]
- void OnCallback( );
- }
#T#使用回調對象時,需要考慮到客戶端代理可能會被關閉,如果此時調用回調,就會引發一個ObjectDisposedException異常。“因此,對于客戶端而言,當它不再需要接收回調或者客戶端應用程序已經關閉時,***能夠通知服務。”本書給出了解決這一問題的方法,就是為服務契約增加兩個操作 Connect()與Disconnect()。其中,Disconnect()正是起到了通知服務的作用,它在客戶端代理關閉的情況下,可以將當前的WCF回調對象引用從列表中移除。至于Connect()方法則是出于對稱的目的而引入,但引入它還有一個好處是,它可以使得客戶端能夠多次地連接或斷開。實現 Connect()與Disconnect()方法的代碼如下:
- static List<IMyContractCallback> m_Callbacks = new List<IMyContractCallback>( );
- public void Connect( )
- {
- IMyContractCallback callback = OperationContext.Current.
- GetCallbackChannel<IMyContractCallback>( );
- if(m_Callbacks.Contains(callback) == false)
- {
- m_Callbacks.Add(callback);
- }
- }
- public void Disconnect( )
- {
- IMyContractCallback callback = OperationContext.Current.
- GetCallbackChannel<IMyContractCallback>( );
- if(m_Callbacks.Contains(callback) == true)
- {
- m_Callbacks.Remove(callback);
- }
- else
- {
- throw new InvalidOperationException("Cannot find callback");
- }
- }