程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> Effective C#原則21:用委托來表示回調

Effective C#原則21:用委托來表示回調

編輯:關於C#

我:“兒子,到院子裡除草去,我要看會書。”

斯科特: “爸,我已經打掃過院子了。”

斯科特:“爸,我已經 把草放在除草機上了。”

斯科特:“爸,除草機不能啟動了 。”

我:“讓我來啟動它。”

斯科特:“ 爸,我做好了。”

這個簡單的交互展示了回調。我給了我兒子一個 任務,並且他可以報告狀態來(重復的)打斷我。而當我在等待他完成任務的每一 個部份時,我不用阻塞我自己的進程。他可以在有重要(或者事件)狀態報告時, 可以定時的打斷我,或者向我詢求幫助。回調就是用於異步的提供服務器與客戶 之間的信息反饋。它們可能在多線程中,或者可能是簡單的提供一個同步更新點 。在C#裡是用委托來表示回調的。

委托提供了一個類型安全的回調定義 。盡管委托大多數是為事件使用的,但這不應該是C#語言中唯一使用這一功能的 地方。任何時候,如果你想在兩個類之間進行通信,而你又期望比使用接口有更 少的偶合性,那麼委托是你正確的選擇。委托可以讓你在運行確定(回調)目標並 且通知用戶。委托就是包含了某些方法的引用。這些方法可以是靜態方法,也可 以是實例方法。使用委托,你可以在運行時確定與一個或者多個客戶對象進行交 互。

多播委托包含了添加在這個委托上的所有單個函數調用。有兩點要 注意的:它不是異常安全的,並且返回值總是委托上最後一個函數調用後返回的 值。

在多播委托調用的內部,每一個目標都會成功的調用。委托不會捕 獲任何的異常,也就是說,在委托鏈中拋出的任何異常都會終止委托鏈的繼續調 用。

在返回值上也存在一個簡單的問題。你可以定義委托有返回值或者 是void。你可能會寫一個回調函數來檢測用戶的異常中斷:

public delegate bool ContinueProcessing();
public void LengthyOperation( ContinueProcessing pred )
{
  foreach( ComplicatedClass cl in _container )
 {
   cl.DoLengthyOperation();
  // Check for user abort:
  if (false == pred())
   return;
 }
}

在單 委托上這是工作的,但在多播委托上卻是有問題的:

ContinueProcessing cp = new ContinueProcessing (
  CheckWithUser );
cp += new ContinueProcessing( CheckWithSystem );
c.LengthyOperation( cp );

從委托的調用上返回的值 ,其實是它的最後一個函數的調用上返回的值。其它所有的的返回值都被忽略。 即,從CheckWithUser()返回的斷言被忽略。

你可以自己手動的設置兩個 委托來調用兩個函數。你所創建的每一個委托都包含有一個委托鏈。直接檢測這 個委托鏈,並自己調用每一個委托:

public delegate bool ContinueProcessing();
public void LengthyOperation( ContinueProcessing pred )
{
 bool bContinue = true;
  foreach( ComplicatedClass cl in _container )
 {
   cl.DoLengthyOperation();
  foreach( ContinueProcessing pr in
   pred.GetInvocationList( ))
   bContinue &= pr ();
  if (false == bContinue)
   return;
 }
}

這時,我已經定義好了程序的語義,因此委托鏈上的每個委 托必須返回真以後,才能繼續調用。

委托為運行時回調提供了最好的方 法,用戶簡單的實現用戶對類的需求。你可以在運行時確定委托的目標。你可以 支持多個用戶目標,這樣,用戶的回調就可以用.Net裡的委托實現了。

返回教程目錄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved