事件驅動處理

事件驅動處理(Event-driven processing)是指在持續事務管理過程中,進行決策的一種策略,即跟隨當前時間點上出現的事件,調動可用資源,執行相關任務,使不斷出現的問題得以解決,防止事務堆積的處理過程。

基本定義

所謂事件驅動處理,簡單地說就是你點什麼按鈕(即產生什麼事件),電腦執行什麼操作(即調用什麼函式)。當然事件不僅限於用戶的操作。事件驅動的核心自然是事件。

從事件角度說,事件驅動程式的基本結構是由一個事件收集器、一個事件傳送器和一個事件處理器組成。

事件收集器專門負責收集所有事件,包括來自用戶的(如滑鼠、鍵盤事件等)、來自硬體的(如時鐘事件等)和來自軟體的(如作業系統、應用程式本身等)。

事件傳送器負責將收集器收集到的事件分發到目標對象中。

事件處理器做具體的事件回響工作,它往往要到實現階段才完全確定,因而需要運用虛函式機制(函式名往往取為類似於HandleMsg的一個名字)。對於框架的使用者來說,他們唯一能夠看到的是事件處理器。這也是他們所關心的內容。

視圖(即我們通常所說的“視窗”)是“事件驅動”應用程式的另一個要元。它是我們所說的事件傳送器的目標對象。視圖接受事件並能夠對其進行處理。當我們將事件傳送到具體的視圖時,實際上我們完成了一個根本性的變化:從傳統的流線型程式結構到事件觸發方式的轉變。這樣應用程式具備相當的柔性,可以應付種種離散的、隨機的事件。

用戶動作產生的事件

用戶動作 源對象 事件類
單擊按鈕 JButton ActionEvent
單擊複選框 JCheckBox ItemEvent, ActionEvent
單擊單選框 JRadioButton ItemEvent, ActionEvent
在文本框裡按回車鍵 JTextField ActionEvent
選擇一個新項目 JComboBox ItemEvent, ActionEvent
視窗打開、關閉等 Window WindowEvent
滑鼠按下、釋放等 Component MouseEvent
鍵盤按鈕、釋放等 Component KeyEvent

要理解事件驅動和程式,就需要與非事件驅動的程式進行比較。實際上,現代的程式大多是事件驅動的,比如多執行緒的程式,肯定是事件驅動的。早期則存在許多非事件驅動的程式,這樣的程式,在需要等待某個條件觸發時,會不斷地檢查這個條件,直到條件滿足,這是很浪費cpu時間的。而事件驅動的程式,則有機會釋放cpu從而進入睡眠態(注意是有機會,當然程式也可自行決定不釋放cpu),當事件觸發時被作業系統喚醒,這樣就能更加有效地使用cpu.

再說什麼是事件驅動的程式。一個典型的事件驅動的程式,就是一個死循環,並以一個執行緒的形式存在,這個死循環包括兩個部分,第一個部分是按照一定的條件接收並選擇一個要處理的事件,第二個部分就是事件的處理過程。程式的執行過程就是選擇事件和處理事件,而當沒有任何事件觸發時,程式會因查詢事件佇列失敗而進入睡眠狀態,從而釋放cpu。

事件驅動的程式,必定會直接或者間接擁有一個事件佇列,用於存儲未能及時處理的事件。

事件驅動的程式的行為,完全受外部輸入的事件控制,所以,事件驅動的系統中,存在大量這種程式,並以事件作為主要的通信方式。

事件驅動的程式,還有一個最大的好處,就是可以按照一定的順序處理佇列中的事件,而這個順序則是由事件的觸發順序決定的,這一特性往往被用於保證某些過程的原子化。

目前windows,linux,nucleus,vxworks都是事件驅動的,只有一些單片機可能是非事件驅動的。

Windows作業系統下

由於Windows本身是基於“事件驅動”模型的。因而在Windows作業系統下實現應用程式框架有相當的便利。在事件驅動程式的基本單元中,事件收集器已經由Windows系統完成;事件傳送器也已經由Windows完成了部分內容。之所以是部分而非完全是因為Windows是用C語言實現的,而不是C++。由於沒有對象,Windows將事件傳送到所謂的“視窗函式”中(儘管不是傳送到具體的對象,但應該說這是面向對象方式實現的一個變體)。要感謝Windows做了這件事。確定事件的目標所要做的工作的複雜可能要超出我們的想像。

wxWidgets的中所有可以處理事件的類都繼承自wxEvtHandler,其中包含frames,buttons,menus,even documents,所有的窗體類(即從wxWindow繼承的類)和程式類(application class).

這些類可以有一個事件表,用來綁定事件和被調用的函式(handler functions).

過程

•建立一個靜態事件表(即編譯時生成的事件表)的操作步驟

•建立一個新類(直接或間接從wxEvtHandler繼承)

•為每個要處理的事件聲明被調用的函式

•在被處理的事件所在的類的聲明中加入宏DECLARE_EVENT_TABLE

•在宏BEGIN_EVENT_TABLE... END_EVENT_TABLE(就是事件表)中將函式與枚舉的數字綁定(因為產生該類型的事件的按鈕不唯一,要用枚舉數來區分);有些事件不必與枚舉數綁定,因為產生該類型的事件的對象可以確定(比如就是this).

一個事件表

BEGIN_EVENT_TABLE(MyFrame,wxFrame)

EVT_MENU (wxID_ABOUT,MyFrame::OnAbout)

EVT_MENU (wxID_EⅪT,MyFrame::OnQuit)

EVT_SIZE (MyFrame::OnSize)

//不必與枚舉數綁定,因為產生該類型的事件的對象是this

EVT_BUTTON (wxID_OK,MyFrame::OnButtonOK)

END_EVENT_TABLE()

在事件中指定被綁定的數字,wxWidgets會將其映射到對應的函式,並調用函式

所有在事件表中被綁定的函式有相似的形式:返回值都是void,不是virtual函式,參數為wxCommandEvent類型

事件驅動處理程式

為需要處理的事件編寫相應的事件處理程式。要理解事件驅動和程式,就需要與非事件驅動的程式進行比較。實際上,現代的程式大多是事件驅動的,比如多執行緒的程式,肯定是事件驅動的。早期則存在許多非事件驅動的程式,這樣的程式,在需要等待某個條件觸發時,會不斷地檢查這個條件,直到條件滿足,這是很浪費cpu時間的。而事件驅動的程式,則有機會釋放cpu從而進入睡眠態(注意是有機會,當然程式也可自行決定不釋放cpu),當事件觸發時被作業系統喚醒,這樣就能更加有效地使用cpu。

為需要處理的事件編寫相應的事件處理程式。代碼在事件發生時執行。

delphi和java編程特點

n事件(event)表示程式某件事發生的信號。事件分為:

o外部事件:由外部用戶動作產生的事件。例如,點擊滑鼠、按鍵盤。

o內部事件:由系統內部產生的事件。例如,定時器事件。

n源對象(source object)是產生事件的對象。

事件處理驅動的一般步驟

1、確定回響事件的元素

2、為指定元素確定需要回響的事件類型

3、為指定元素的指定事件編寫相應的事件處理程式

4、將事件處理程式綁定到指定元素的指定事件

事件類 事件類

每個事件對象包含與該事件相關的屬性。getSource()方法可以獲取事件的源對象。

事件驅動處理庫

通常,我們寫伺服器處理模型的程式時,有以下幾種模型:

(1)每收到一個請求,創建一個新的進程,來處理該請求;

(2)每收到一個請求,創建一個新的執行緒,來處理該請求;

(3)每收到一個請求,放入一個事件列表,讓主進程通過非阻塞I/O方式來處理請求

上面的幾種方式,各有千秋,

第(1)種方法,由於創建新的進程的開銷比較大,所以,會導致伺服器性能比較差,但實現比較簡單。

第(2)種方式,由於要涉及到執行緒的同步,有可能會面臨死鎖等問題。

第(3)種方式,在寫應用程式代碼時,邏輯比前面兩種都複雜。

綜合考慮各方面因素,一般普遍認為第(3)種方式是大多數網路伺服器採用的方式——事件驅動處理庫。

相關詞條

熱門詞條

聯絡我們