熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

C#事件(Event)解析

2013-11-13 12:21:08  來源: .NET編程 

  事件(event)這個詞兒對於初學者來說往往總是顯得有些神秘不易弄懂而這些東西卻往往又是編程中常用且非常重要的東西大家都知道windows消息處理機制的重要其實C#事件就是基於windows消息處理機制的只是封裝的更好讓開發者無須知道底層的消息處理機制就可以開發出強大的基於事件的應用程序來

  先來看看事件編程有哪些好處

  在以往我們編寫這類程序中往往采用等待機制為了等待某件事情的發生需要不斷地檢測某些判斷變量而引入事件編程後大大簡化了這種過程

   使用事件可以很方便地確定程序執行順序

   當事件驅動程序等待事件時它不占用很多資源事件驅動程序與過程式程序最大的不同就在於程序不再不停地檢查輸入設備而是呆著不動等待消息的到來 每個輸入的消息會被排進隊列等待程序處理它如果沒有消息在等待則程序會把控制交回給操作系統以運行其他程序

   事件簡化了編程操作系統只是簡單地將消息傳送給對象由對象的事件驅動程序確定事件的處理方法操作系統不必知道程序的內部工作機制只是需要知道如何與對象進行對話也就是如何傳遞消息

  有了這麼多好處看來我們的確有必要掌握它俗話說難了不會會了不難就讓我們一步一步開始吧

  要講事件必然要講到委托(delegate)它們之間的關系可以通過一個淺顯的比方來說明這個比方可能不是十分恰當比如你要租一個房屋這是一個事件那麼委托就是房屋租賃中介當你把租房子的消息告知中介後中介就會產生出一套符合你要求的房屋租賃方案來再由中介執行這套方案你便租得了這個房屋即事件被處理了當然你也可以不通過中介直接找房東但如果沒有互聯網等工具你如何得到誰出租房屋的信息?話題扯遠了

  委托(delegate)

  委托可以理解成為函數指針不同的是委托是面向對象而且是類型安全的關於委托的理解可以參考我的另一篇文章《C#委托之個人理解》

  事件(event)

  我們可以把事件編程簡單地分成兩個部分事件發生的類(書面上叫事件發生器)和事件接收處理的類事件發生的類就是說在這個類中觸發了一個事件但這個類並不知道哪個個對象或方法將會加收到並處理它觸發的事件所需要的是在發送方和接收方之間存在一個媒介這個媒介在NET Framework中就是委托(delegate)在事件接收處理的類中我們需要有一個處理事件的方法好了我們就按照這個順序來實現一個捕獲鍵盤按鍵的程序來一步一步說明如何編寫事件應用程序

  首先創建一個自己的EventArgs類

  引自MSDN:

  EventArgs是包含事件數據的類的基類此類不包含事件數據在事件引發時不向事件處理程序傳遞狀態信息的事件會使用此類如果事件處理程序需要狀態信息則應用程序必須從此類派生一個類來保存數據

  因為在我們鍵盤按鍵事件中要包含按鍵信息所以要派生一個KeyEventArgs類來保存按鍵信息好讓後面知道按了哪個鍵

  internal class KeyEventArgs : EventArgs
  {
   private char keyChar;
   public KeyEventArgs( char keyChar ) : base()
   {
    thiskeyChar = keyChar;
   }
   public char KeyChar
   {
    get
    {
     return keyChar;
    }
   }
  }

  再創建一個事件發生的類KeyInputMonitor這個類用於監控鍵盤按鍵的輸入並觸發一個事件

  internal class KeyInputMonitor
  {
   // 創建一個委托返回類型為void兩個參數
   public delegate void KeyDown( object sender KeyEventArgs e );
   // 將創建的委托和特定事件關聯在這裡特定的事件為OnKeyDown
   public event KeyDown OnKeyDown;
   public void Run()
   {
   bool finished = false;
   do
    {
     ConsoleWriteLine( Input a char );
     string response = ConsoleReadLine();
     char responseChar = ( response == ) ? : charToUpper( response[] );
     switch( responseChar )
     {
      case X:
      finished = true;
      break;
      default:
      // 得到按鍵信息的參數
      KeyEventArgs keyEventArgs = new KeyEventArgs( responseChar );
      // 觸發事件
      OnKeyDown( this keyEventArgs );
      break;
     }
    }while( !finished );
   }
  }

  這裡注意OnKeyDown( this KeyEventArgs );一句這就是觸發事件的語句並將事件交由KeyDown這個委托來處理委托指定事件處理方法去處理事件這就是事件接收方的類的事情了參數 this是指觸發事件的對象就是本身這個對象keyEventArgs包含了按鍵信息

  最後創建一個事件接收方的類這個類先產生一個委托實例再把這個委托實例添加到產生事件對象的事件列表中去這個過程又叫訂閱事件然後提供一個方法回顯按鍵信息

  internal class EventReceiver
  {
   public EventReceiver( KeyInputMonitor monitor )
   {
    // 產生一個委托實例並添加到KeyInputMonitor產生的事件列表中
    monitorOnKeyDown += new KeyInputMonitorKeyDown( thisEcho );
   }
   private void Echo(object sender KeyEventArgs e)
   {
    // 真正的事件處理函數
    ConsoleWriteLine( Capture key: {} eKeyChar );
   }
  }

  看一下如何調用

  public class MainEntryPoint
  {
   public static void Start()
   {
    // 實例化一個事件發送器
    KeyInputMonitor monitor = new KeyInputMonitor();
    // 實例化一個事件接收器
    EventReceiver eventReceiver = new EventReceiver( monitor );
    // 運行
    monitorRun();
   }
  }

  總結

  C#中使用事件需要的步驟

  創建一個委托

  將創建的委托與特定事件關聯(Net類庫中的很多事件都是已經定制好的所以他們也就有相應的一個委托在編寫關聯事件處理程序也就是當有事件發生時我們要執行的方法的時候我們需要和這個委托有相同的簽名)

  編寫事件處理程序

  利用編寫的事件處理程序生成一個委托實例

  把這個委托實例添加到產生事件對象的事件列表中去這個過程又叫訂閱事件

  C#中事件產生和實現的流程

  定義A為產生事件的實例a為A產生的一個事件

  定義B為接收事件的實例b為處理事件的方法

  A由於用戶(程序編寫者或程序使用者)或者系統產生一個a事件(例如點擊一個Button產生一個Click事件)

  A通過事件列表中的委托對象將這個事件通知給B

  B接到一個事件通知(實際是Bb利用委托來實現事件的接收)

  調用Bb方法完成事件處理


From:http://tw.wingwit.com/Article/program/net/201311/15725.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.