1. 程式人生 > 其它 >C#中的程序檢測退出事件和座位狀態改變事件深入淺出談談EventHandler的使用

C#中的程序檢測退出事件和座位狀態改變事件深入淺出談談EventHandler的使用

關於程序

之前我在啟動我的師生對講的exe的時候,都是直接呼叫Process類的靜態函式Process.Start(System.String AppPath,System.String Arguments) 來直接啟動一個exe,這樣當然是可以的,但是當我們的程序退出或者意外崩潰的時候,卻沒有辦法對這個程序進行相關的檢測,也就是說如果程序中途退出了的話,可能會導致整個框架的互斥等狀態未發生改變,這個時候就需要用到一個程序物件

也就是說我們可以先例項化一個程序的物件Process p_VideoMeet,然後再用這個程序p_VideoMeet來表示我們整個執行著的程序,也就不用再做一些沒什麼含義的啟動檢測啊,狀態碼之類的東西了。所以對於此,我在這裡寫一個相關的例項。

比如我現在一個類,LBD_VideoMeet類,我可能在這個類內啟動兩個程序之中的一個,之前我們在使用的時候,是直接通過Process.Start這個靜態函式啟動,然後記錄其啟動的狀態,其實這樣的呼叫容易導致一些混亂的狀態,而且有可能程式的意外退出,如果崩潰的話就沒法知道當前的程序狀態了,沒有通知的情況,會導致無法獲得互斥狀態,如果這樣的話,就沒法清除當前狀態了。

那麼現在來上例項。

假設我們現在可以獲得兩個程式,Intercom.exe和 Broadcast.exe的啟動路徑和啟動引數,而且當我們啟動的時候就會向我們的框架中傳送控制代碼,那我們現在應該怎麼做呢?

首先我們當然是希望開啟的子程序不脫離我們的主程序,也就是我們在主程序中可以有完整的子程序,所以不能像野狗拉屎一樣,把子程序拉出來放在大街上隨風而去就完了(當然考慮到高內聚低耦合的原則,這肯定是最好的狀態,開啟的子程序有完整獨立的功能,而需要整合其中的程式用dll來表示,但是開發中難免有些妥協,比如開源,或者跨語言的程式,或者像我這樣的新手寫dll沒法保證記憶體和執行緒的安全性)

那我們就用一個程序來表示我們現在需要啟動的程序 Process p_VideoMeet,因為Intercom和Broadcast是互斥的,所以兩個共享一個程序類就行了,反正這個程序退出的時候也會釋放掉所有的資源,所以不需要操心。甚至這樣操作可以省去很多不必要的判別,直接釋放程序類資源即可。

原先沒有參悟到這個精髓寫出來的大便現在再回過頭來看真是令人羞愧,但是能跑告訴公路的大便,誰在乎他會不會有輪子呢?

我們先設定一個程序物件

 Process p_VideoMeet = null;

啟動程序的方法:

 public void StartProcess(System.String strAppPath, System.String Argus)
      {
          try
          {
              if(this.p_VideoMeet == null)
              {
                  p_VideoMeet = new Process();
              }

              p_VideoMeet.StartInfo.FileName = strAppPath; //啟動程序具體路徑
              p_VideoMeet.StartInfo.Arguments = Argus; //啟動項引數
              p_VideoMeet.StartInfo.UseShellExecute = false;//是否使用作業系統shell啟動
              p_VideoMeet.StartInfo.RedirectStandardInput = true;//接受來自呼叫程式的輸入資訊
              p_VideoMeet.StartInfo.RedirectStandardOutput = false;//由呼叫程式獲取輸出資訊
              p_VideoMeet.StartInfo.RedirectStandardError = true;//重定向標準錯誤輸出
              p_VideoMeet.StartInfo.CreateNoWindow = false;//不顯示程式視窗
              p_VideoMeet.EnableRaisingEvents = true;

              //意外退出的話,我這邊也可以得到訊息了
              p_VideoMeet.Exited += this.P_Exited;

              p_VideoMeet.Start();

          }
          catch (Exception e)
          {
              WriteErrorMessage("CheckClientExitMessages:" + e.Message);

          }
      }

意外退出事件

public static event EventHandler ExitedEvent;

private static void P_Exited(object sender, EventArgs e)
{
    if (ExitedEvent!=null)
    {
        ExitedEvent(sender,e);
    }   
}

最偉大的設計,就是最簡單的設計。

關於事件和委託

其實我個人在開發過程中是比較牴觸事件和委託這個叫法的,就有點像socket通訊裡管socket叫套接字 這種翻譯一樣,即使到了我還是覺得所謂的套接字沒有 發包 這兩個字來的簡介明瞭。

如果要換一種說法,我們要怎麼理解呢?其實就像是觸發器和接收器 -- 當我們按下觸發器之後,所有的接收器都會接到觸發器傳送來的訊號。打個比方,就好像烽火狼煙,我一點火,所有的哨站就知道開幹了,這種情況下烽火只能傳遞一個簡單訊號:起火等於開幹,但是這也是隻有其他哨所才懂其中的含義;或者海上的燈塔,按照一定的頻率和強度打訊號,海上的漁船就能看得懂燈塔打來的訊號,這樣傳遞的資訊就更加複雜了,這些傳遞的資訊也只有這個海域的漁船們才會懂,不同的海域可能會有不同的約定俗成的訊號模式。

C#的事件委託大致和我上面說的這兩種模型差不多,都分為 1.觸發器,即傳送訊號的方法 2.接收器,即接收到訊號並觸發行為的方法

之前我也有些過一篇部落格,有關於事件和委託相關的內容的,詳情見下方部落格

軒先生-主框架程式碼中,關於委託的一些事,開發日誌