麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

[連載]《C#通訊(串口和網絡)框架的設計與實現》-8.總體控制器的設計

2019-11-14 13:42:26
字體:
來源:轉載
供稿:網友

目       錄

第八章           總體控制器的設計... 2

8.1           總控制器的職能... 2

8.2           組裝和釋放部件... 3

8.3           事件響應... 5

8.4           小結... 9

 

第八章     總體控制器的設計

    有了IO部分、設備驅動部分、顯示部分、數據導出部分和服務組件部分等,在這些已經存在的接口上構建一個集成各部分的總控制器,協調各部分有序工作、事件響應和控制數據流向。

    另外,這個總控制器還負責與宿主程序進行交互,可以這樣理解:總控制器是宿主程序與IO部分、設備驅動部分、顯示部分、數據導出部分和服務組件部分之間交互的載體,并且是唯一的。結構示意圖如下:

 

8.1    總控制器的職能

   總控制器(IDeviceController)的職能包括:增加和刪除設備驅動、增加導出數據實例、增加圖形顯示實例、增加服務組件實例、單擊服務事件、釋放控制器資源等等。接口定義如下圖:

 

8.2    組裝和釋放部件

     DeviceController是總控制器的實例體類,繼承自IDeviceController接口。通過構造函數來完成對總控制器的初始化,代碼如下:

public DeviceController(){       _devList = DeviceManager.GetInstance();       _ioController = IOControllerManager.GetInstance();       _runContainer = RunContainerForm.GetRunContainer();       _runContainer.MouseRightContextMenuHandler += RunContainer_MouseRightContextMenuHandler;       _dataShowController = new GraphiCSShowController();       _exportController = new ExportDataController();       _appServiceManager = new AppServiceManager();}

   通過ReleaseDeviceController接口來完成對總控制器的資源釋放,代碼如下:

public void ReleaseDeviceController(){       _ioController.RemoveAllController();       _runContainer.RemoveAllDevice();       _runContainer.MouseRightContextMenuHandler -= RunContainer_MouseRightContextMenuHandler;       _exportController.RemoveAll();       _dataShowController.RemoveAll();       _appServiceManager.RemoveAll();       IEnumerator<IRunDevice> devList = _devList.GetEnumerator();       while (devList.MoveNext())       {              devList.Current.ExitDevice();       }       _devList.RemoveAllDevice();}

     軟件退出時釋放資源要比軟件啟動時加載資源要復雜的多,這塊涉及到兩方面問題:(1)釋放資源順序,如果資源提前釋放,那么往往會造成后邊代碼在執行過程中出現無法引用對象資源的現象,造成意想不到的結果,所以一定要對實例的可用性進行判斷。(2)事務性的線程無法正常退出,造成軟件界面已經關閉,但是后臺進程卻一直存在。特別是對線程退出的處理,框架平臺采用了統一的線程退出機制,代碼如下:

public void StartThead(){       if (_RunThread == null || !_RunThread.IsAlive)       {              this._IsExit = false;              this._RunThread = new Thread(new ThreadStart(RunThead));              this._RunThread.IsBackground = true; //該線程為后臺線程              this._RunThread.Name = "RunThread";              this._RunThread.Start();       }}PRivate void RunThead(){       while (!_IsExit)       {              if(_IsExit)         //如果標識為true,則退出循環,退出線程              {                     break;              }              //事務處理       }}public void StopThead(){       if (this._RunThread != null && this._RunThread.IsAlive)       {              this._IsExit = true;       //標識當前線程為可退出線程。              this._RunThread.Join(1000);//阻塞調用線程,直到某個線程終止或經過了指定時間為止              try              {                     _RunThread.Abort();    //為了防止線程沒有退出,進行強行終止,有可能造成文件損壞              }              catch              {              }       }}

8.3    事件響應

     增加和刪除設備驅動都會對設備的事件進行綁定和解綁。代碼如下:

dev.DeviceRuningLogHandler += new DeviceRuningLogHandler(DeviceRuningLogHandler);dev.UpdateContainerHandler += new UpdateContainerHandler(UpdateContainerHandler);dev.DeviceObjectChangedHandler += new DeviceObjectChangedHandler(DeviceObjectChangedHandler);dev.ReceiveDataHandler += new ReceiveDataHandler(ReceiveDataHandler);dev.SendDataHandler += new SendDataHandler(SendDataHandler);dev.COMParameterExchangeHandler += new COMParameterExchangeHandler(COMParameterExchangeHandler);dev.DeleteDeviceHandler += new DeleteDeviceHandler(DeleteDeviceHandler);

     具體含義請參見《第3章 設備驅動的設計》中的“3.12 事件響應設計”,COMParameterExchangeHandler改變串口參數事件響應代碼如下:

private void COMParameterExchangeHandler(object source, COMParameterExchangeArgs e){       if (e == null)       {              return;       }       IRunDevice dev = this._devList.GetDevice(e.DeviceID.ToString());       if (dev != null)       {              if (dev.CommunicationType == CommunicationType.COM)              {                     if (e.OldCOM != e.NewCOM)                     {                            //--------------對舊串口進行處理----------------//                            IRunDevice[] oldCOMDevList = this._devList.GetDevices(e.OldCOM.ToString(), CommunicationType.COM);                            //---------------檢測當前串口設備數------------//                            int existCOMCount = 0;                            for (int i = 0; i < oldCOMDevList.Length; i++)                            {                                   if (oldCOMDevList[i].GetHashCode() != dev.GetHashCode())                                   {                                          existCOMCount++;                                   }                            }                            //------------------------------------------//                            if (existCOMCount <= 0)//該串口沒有可用的設備                            {                                   IIOController oldCOMController = IOControllerManager.GetInstance().GetController(sessionCom.FormatKey(e.OldCOM));                                   if (oldCOMController != null)                                   {                                          _ioController.CloseController(oldCOMController.Key);                                   }                                   else                                   {                                          DeviceMonitorLog.WriteLog(e.DeviceName, "該設備的串口控制器為空");                                   }                            }                            //--------------對新串口進行處理----------------//                            bool newCOMControllerExist = IOControllerManager.GetInstance().ContainController(SessionCom.FormatKey(e.NewCOM));                            if (!newCOMControllerExist)                            {                                   IIOController newCOMController = _ioController.BuildController(e.NewCOM.ToString(), e.NewBaud.ToString(), CommunicationType.COM);                                   if (newCOMController != null)                                   {                                          newCOMController.StartService();                                        _ioController.AddController(newCOMController.Key.ToString(), newCOMController);                                   }                                   else                                   {                                          DeviceMonitorLog.WriteLog(e.DeviceName, "創建該設備的串口控制器失敗");                                   }                            }                            DeviceMonitorLog.WriteLog(e.DeviceName, String.Format("串口從{0}改為{1}", e.OldCOM.ToString(), e.NewCOM.ToString()));                     }                     else                     {                            if (e.OldBaud != e.NewBaud)                            {                                   ISessionCom comIO = (ISessionCom)SessionComManager.GetInstance().GetIO(SessionCom.FormatKey(e.OldCOM));                                   if (comIO != null)                                   {                                          bool success = comIO.IOSettings(e.NewBaud);                                          if (success)                                          {                                                 DeviceMonitorLog.WriteLog(e.DeviceName, String.Format("串口{0}的波特率從{1}改為{2}成功", e.OldCOM.ToString(), e.OldBaud.ToString(), e.NewBaud.ToString()));                                          }                                          else                                          {                                                 DeviceMonitorLog.WriteLog(e.DeviceName, String.Format("串口 {0} 的波特率從 {1} 改為 {2} 失敗", e.OldCOM.ToString(), e.OldBaud.ToString(), e.NewBaud.ToString()));                                          }                                   }                            }                     }              }              else              {                     DeviceMonitorLog.WriteLog(e.DeviceName, "不是串口類型的設備");              }       }}

    同時,還包括GraphicsShowClosedHandler和MouseRightContextMenuHandler兩個事件。當關閉顯示視圖的時候會觸發GraphicsShowClosedHandler事件,把當前視圖從管理器中移除,并釋放資源;當右鍵單擊顯示視圖會觸發MouseRightContextMenuHandler事件,以調用相應設備的上下文菜單。

8.4    小結

    總體控制器不是必須的,宿主程序完全可以直接與IO部分、設備驅動部分、顯示部分、數據導出部分和服務組件部分進行交互。但是,為了結構清晰、方便擴展,在中間加了一層進行總體協調。

 

作者:唯笑志在

Email:504547114@QQ.com

QQ:504547114

.NET開發技術聯盟:54256083

文檔下載:http://pan.baidu.com/s/1pJ7lZWf

官方網址:http://www.bmpj.net


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久久国产综合精品 | 亚洲成人国产 | 欧美一级高潮 | 奇米888一区二区三区 | 日韩视频在线观看免费 | 成人免费福利视频 | 极品大长腿啪啪高潮露脸 | 亚州欧美在线 | 亚洲精品成人久久久 | av之家在线观看 | 日本精品视频一区二区三区四区 | 国产伊人色 | 亚洲一级片免费观看 | av在线等 | 欧美一区二区精品夜夜嗨 | 国产精品一区二区x88av | 国产一级午夜 | 欧美成人性生活片 | 黄视频网址| 特级毛片a级毛片100免费 | 777zyz色资源站在线观看 | 亚洲影院在线 | av在线免费观看网 | 久草在线视频首页 | 午夜视频观看 | 黄色av网站免费看 | 成人免费网站在线观看 | 99国语露脸久久精品国产ktv | 小雪奶水翁胀公吸小说最新章节 | 成人免费影院 | 久久99精品久久久久久秒播蜜臀 | 伊人成人免费视频 | www.热 | 99精品视频网站 | 精品一区二区三区免费 | 国产二区三区在线播放 | 欧美成人综合视频 | 中文字幕在线网 | 宅男视频在线观看免费 | 第一区免费在线观看 | 精品一区二区三区免费毛片 |