2009-09-04 131 views
0

今天我有一個WCF問題,儘管它也可能與.NET中的其他網絡模型有關。WCF:DuplexSessionChannel,異步操作和異常

我有一個公開發送(消息)OperationContract,這是OneWay = true的WCF服務。現在這個服務有一個回調通道來將消息返回給客戶端。

無論如何,我想(成功)從我的客戶端異步調用此發送方法。在DuplexSessionChannel上,我調用BeginSend(Message,OnSendComplete,null),並且我有一個在DuplexSessionChannel上調用EndSend(asyncResult)的OnSendComplete(IAsyncResult)方法。

該服務有一個CallbackContract並使用相同的BeginSend()/ EndSend()模式發送回客戶端,這是在我用OperationContext.Current.GetCallbackChannel獲得的callBack通道上調用的。

從服務回調通道接收消息時,其DuplexSessionChannel上的客戶端調用BeginReceive()/ EndReceive()。

即使事情正常,我不明白END <Operation>()方法實際上做了什麼,這是我需要向我解釋的。

我問,因爲我在Service中調用EndSend()時偶爾發生異常(發送回客戶端)抱怨集合已被修改(我知道這個異常意味着什麼,但不知道它爲什麼是發生或確切地...)。我正在使用PollingDuplexHttpBinding和Silverlight客戶端。

我不是WCF的專家,但不要阻擋細節,我需要知識。到目前爲止,我在職業生涯中的其他異步操作之前已經看到了這些開始/結束模式,但從來沒有真正理解發生了什麼。

在此先感謝。

回答

1

這聽起來像你的問題是關於開始/結束APM(異步編程模型)。簡言之,APM採用類

R Foo(A a); // R is some result type, A is some argument type 

同步方法和把它分成異步BeginFoo和EndFoo方法。當操作正在進行一些可能長時間運行的真正異步的系統操作(例如與網絡交談)時(至少與其他功能相比,例如與網絡交談可能需要幾百毫秒或更多),主要優勢纔會發生。該模式爲您提供了一種方法來告訴系統啓動操作,然後在操作結果準備就緒時再給您回電。這種模式的優點是,當這個調用未決時(也就是說,例如,您可以擁有數千個待處理的網絡讀取/寫入,而不需要數千個線程,萬智牌,線程昂貴),則不必阻塞託管線程。因此,'BeginFoo'是你如何說'用這些參數啓動方法',然後當你被回調(作爲結果已經準備就緒的通知)時,'EndFoo'是你如何得到結果。在一般情況下,如果'Foo'可能拋出一個特定的異常,那麼這個異常可能來自'Begin'調用或'End'調用,你必須準備好在兩個地方處理它。

在發送類似Send()的情況下(它可能會返回void?我忘記了),這有點令人討厭/怪異,因爲它是單向的,你只是想「開火而忘記」。但是例外情況仍然可能發生(例如,我嘗試發送,但有人拔掉了我的網線),因此這可能會產生異常......並且給定Begin/End APM,這種異常可能來自EndSend調用。實際上,異常是調用Send的一種「結果」,所以調用EndSend提供了一種方法,讓系統在您調用BeginSend之後向您發出異常以說出事情出錯。

+0

在WCF中,IDuplexSessionChannel.BeginSend和EndSend具有以下簽名: IAsyncResult BeginSend(Message,AsyncCallback,object) void EndSend(IAsyncResult); 我從傳遞給BeginSend的AsyncCallback委託調用的回調方法內部調用EndSend。鑑於EndSend()返回無效,我仍然不明白它是什麼。我看到它的「結果」來自BeginSends AsyncCallback。我也不明白爲什麼BeginSend返回IAsyncResult,當它也由BeginSend AsyncCallback異步返回時。 – MrLane 2009-09-09 01:30:07

+0

閱讀Brians後發佈幾個月後,我發佈了這個問題,這種模式更加清晰。 Juval Lowery的編程WCF書也很好地解釋了這一點。我仍然不知道異常的原因,但它已被淘汰,因爲我不再調用EndSend(),因爲我意識到無論如何都沒有返回任何結果。我不知道這是否是好的做法(也許我可能會錯過異常細節),但是這本書似乎暗示它可以被省略,並且因爲刪除東西已經好很多。 – MrLane 2010-02-02 04:28:50