21.使用委托表达回调
回調用于為服務器和客戶端之間提供異步的反饋,其中可能會涉及到多線程或者需要提供一個入口點用于同步更新,在C#中,我們使用委托來表達回調。
委托為我們提供了類型安全的回調定義,雖然大多數常見的委托應用都和事件相關,但是那并不是委托應用的全部場合。當類之間有通信的需要,并且我們期望一種比接口更加松耦合的機制時,委托就是最合適的選擇。委托允許我們在運行時配置目標,并且可以通知多個對象,委托對象中包含一個方法引用,這個方法可以是靜態方法,也可以是實例方法。
我們還可以為委托綁定多個方法,利用委托的多播機制,可以一次調用多個方法。但是有兩點需要注意:1)如果有委托調用出現異常,那么這種構造將不能保證安全;2)整個多播調用的返回值是最后一個調用的方法的返回值。
在一個多播委托調用的過程中,每一個目標都會被順次調用,委托對象本身不會捕捉任何異常,因此,任何目標拋出的異常都會結束委托鏈的調用。
同樣,委托的返回值也有同樣的問題,如果委托的返回值類型不是void,那么對于一個多播委托來說,最后的返回值就是委托鏈上執行的最后一個方法,其他的返回值都會被忽略。
我們來看下面的代碼。
?publicdelegatebool ContinueProcessing();
publicvoid LengthyOperation( ContinueProcessing pred )
{
? foreach( ComplicatedClass cl in _container )
? {
??? cl.DoLengthyOperation();
??? // Check for user abort:
??? if (false== pred())
????? return;
? }
}
//Test
ContinueProcessing cp =new ContinueProcessing (
? CheckWithUser );
cp +=new ContinueProcessing( CheckWithSystem );
c.LengthyOperation( cp );
上述代碼在執行過程中,就會忽略CheckWithUser()方法的返回值。
?
我們可以自己手動遍歷委托鏈來解決這個問題,來看下面的代碼。
?publicdelegatebool ContinueProcessing();
2
3 publicvoid LengthyOperation( ContinueProcessing pred )
4 {
5 ? bool bContinue =true;
6 ? foreach( ComplicatedClass cl in _container )
7 ? {
8 ??? cl.DoLengthyOperation();
9 ??? foreach( ContinueProcessing pr in
10 ????? pred.GetInvocationList( ))
11
12 ????? bContinue &= pr();
13
14 ??? if (false== bContinue)
15 ????? return;
16 ? }
17 }
?
上述代碼中,我們調用GetInvocationList()方法來手動遍歷委托鏈,這樣就可以解決上面提到的CheckWithUser()方法返回值被忽略的問題。
?
委托為我們提供了一種在運行時進行回調的最好方式,這種方式對客戶類只有非常簡單的要求,我們可以在運行時配置委托目標。另外,委托也支持多播,在.NET中,我們應該使用委托的方式來實現回調。
轉載于:https://www.cnblogs.com/movemoon/archive/2012/10/25/2738435.html
總結
以上是生活随笔為你收集整理的21.使用委托表达回调的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU 1848 Fibonacci a
- 下一篇: 关于navicat连接oracle 报