国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

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

[連載]《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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 浦江县| 申扎县| 大田县| 新平| 大荔县| 和林格尔县| 奉化市| 南华县| 云梦县| 将乐县| 房产| 东平县| 桐庐县| 丹巴县| 修武县| 北海市| 马关县| 贡觉县| 台江县| 宁武县| 全南县| 盱眙县| 浮梁县| 无为县| 正宁县| 碌曲县| 武汉市| 朔州市| 南宫市| 綦江县| 高密市| 萍乡市| 错那县| 达州市| 阿城市| 赞皇县| 贵南县| 娄底市| 博客| 台州市| 定陶县|