From 0ccd6112bbe078fa8d36b9498d77cb90d448a57b Mon Sep 17 00:00:00 2001 From: Leven Date: Thu, 24 Oct 2019 17:13:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DCA1030,=20CA1031?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Models/TimerM.cs | 46 +---- ViewModels/MainWindowBase.cs | 8 +- ViewModels/MainWindowVM.cs | 366 +++++++++++++++++++++-------------- Views/MainWindow.xaml | 2 +- Views/MainWindow.xaml.cs | 41 +++- Views/WPFUpdate.xaml.cs | 2 +- 6 files changed, 273 insertions(+), 192 deletions(-) diff --git a/Models/TimerM.cs b/Models/TimerM.cs index 4cb92e9..b66099b 100644 --- a/Models/TimerM.cs +++ b/Models/TimerM.cs @@ -4,8 +4,12 @@ namespace OSDA.Models { - internal class TimerModel : MainWindowBase, IDisposable + internal class TimerModel : MainWindowBase { + #region 字段 + private static Timer SystemTimer = null; /* 该对象持续存在于整个应用程序运行期间 */ + #endregion + /// /// 状态栏 - 系统时间 /// @@ -26,8 +30,6 @@ public string SystemTime } } - private static Timer SystemTimer = null; - public void InitSystemClockTimer() { SystemTimer = new Timer @@ -47,18 +49,15 @@ private void SystemTimer_Elapsed(object sender, ElapsedEventArgs e) private string SystemTimeData() { - string SystemTime; DateTime systemTime = DateTime.Now; - SystemTime = string.Format(cultureInfo, "{0}年{1}月{2}日 {3}:{4}:{5}", + return string.Format(cultureInfo, "{0}年{1}月{2}日 {3}:{4}:{5}", systemTime.Year.ToString("0000", cultureInfo), systemTime.Month.ToString("00", cultureInfo), systemTime.Day.ToString("00", cultureInfo), systemTime.Hour.ToString("00", cultureInfo), systemTime.Minute.ToString("00", cultureInfo), systemTime.Second.ToString("00", cultureInfo)); - - return SystemTime; } public void TimerDataContext() @@ -67,38 +66,5 @@ public void TimerDataContext() InitSystemClockTimer(); } - - #region IDisposable Support - private bool disposedValue = false; - - /// - /// 受保护的 Dispose 方法实现 - /// - /// - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - /* 释放托管资源(如果需要) */ - } - - SystemTimer.Dispose(); - SystemTimer = null; - - disposedValue = true; - } - } - - /// - /// SerialPort 字段 IDisposable 接口的 Dispose 方法实现(无参数) - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - #endregion } } diff --git a/ViewModels/MainWindowBase.cs b/ViewModels/MainWindowBase.cs index 261024a..51356ae 100644 --- a/ViewModels/MainWindowBase.cs +++ b/ViewModels/MainWindowBase.cs @@ -4,20 +4,20 @@ namespace OSDA.ViewModels { - public class MainWindowBase : INotifyPropertyChanged + internal class MainWindowBase : INotifyPropertyChanged { + public event PropertyChangedEventHandler PropertyChanged; + /// /// 提供区域性信息 /// internal CultureInfo cultureInfo = new CultureInfo(CultureInfo.CurrentUICulture.Name); - public event PropertyChangedEventHandler PropertyChanged; - /// /// 提供属性更改事件的方法 /// /// - public void RaisePropertyChanged([CallerMemberName] string propertyName = null) + internal void RaisePropertyChanged([CallerMemberName] string propertyName = null) { var handler = PropertyChanged; diff --git a/ViewModels/MainWindowVM.cs b/ViewModels/MainWindowVM.cs index 0a0d125..89099c5 100644 --- a/ViewModels/MainWindowVM.cs +++ b/ViewModels/MainWindowVM.cs @@ -18,10 +18,14 @@ namespace OSDA.ViewModels internal class MainWindowViewModel : MainWindowBase, IDisposable { #region 字段 - private SerialPort SerialPortBase = new SerialPort(); - private readonly GitRelease GitReleaseBase = new GitRelease(); + internal SerialPort SerialPortBase = new SerialPort(); - private volatile string DataRecvPath = string.Empty; /* 数据接收路径 */ + internal GitRelease GitReleaseBase = new GitRelease(); + + /// + /// 保存接收,数据保存路径 + /// + private volatile string DataRecvPath = string.Empty; /// /// 用于接收区数据超过32MB时,自动清空接收控件中的数据 @@ -54,9 +58,10 @@ public string DepictInfo #region 菜单栏 #region 文件 - public void ExitWindow() + internal void ExitWindow() { - if ((SerialPortBase != null) && SerialPortBase.IsOpen) + /* 仅当成功在SerialPort对象上调用Open()方法且最近一次没有调用Close()方法时,才返回True */ + if (SerialPortBase.IsOpen) { CloseSP(); } @@ -66,7 +71,7 @@ public void ExitWindow() #region 选项 #region 字节编码 - public void ASCIIEnable() + internal void ASCIIEnable() { SerialPortModel.UTF8Enable = false; SerialPortModel.UTF16Enable = false; @@ -83,11 +88,11 @@ public void ASCIIEnable() } catch(ArgumentException e) { - DepictInfo = string.Format(cultureInfo, "更改字节编码为{0}是非法操作", e.ParamName); + DepictInfo = e.Message; } } - public void UTF8Enable() + internal void UTF8Enable() { SerialPortModel.ASCIIEnable = false; SerialPortModel.UTF16Enable = false; @@ -104,11 +109,11 @@ public void UTF8Enable() } catch (ArgumentException e) { - DepictInfo = string.Format(cultureInfo, "更改字节编码为{0}是非法操作", e.ParamName); + DepictInfo = e.Message; } } - public void UTF16Enable() + internal void UTF16Enable() { SerialPortModel.ASCIIEnable = false; SerialPortModel.UTF8Enable = false; @@ -125,11 +130,11 @@ public void UTF16Enable() } catch (ArgumentException e) { - DepictInfo = string.Format(cultureInfo, "设置字节编码为{0}是非法操作", e.ParamName); + DepictInfo = e.Message; } } - public void UTF32Enable() + internal void UTF32Enable() { SerialPortModel.ASCIIEnable = false; SerialPortModel.UTF8Enable = false; @@ -146,12 +151,12 @@ public void UTF32Enable() } catch (ArgumentException e) { - DepictInfo = string.Format(cultureInfo, "更改字节编码为{0}是非法操作", e.ParamName); + DepictInfo = e.Message; } } #endregion - public void RtsEnable() + internal void RtsEnable() { SerialPortModel.RtsEnable = !(SerialPortModel.RtsEnable); @@ -168,16 +173,15 @@ public void RtsEnable() } catch(InvalidOperationException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]当设置为硬件流或硬软件流时,不允许设置RTS", - e.HResult.ToString("X", cultureInfo)); + DepictInfo = e.Message; } catch (IOException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]端口处于无效状态", e.HResult.ToString("X", cultureInfo)); + DepictInfo = e.Message; } } - public void DtrEnable() + internal void DtrEnable() { SerialPortModel.DtrEnable = !(SerialPortModel.DtrEnable); @@ -194,17 +198,16 @@ public void DtrEnable() } catch (InvalidOperationException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]当设置为硬件流或硬软件流时,不允许设置DTR", - e.HResult.ToString("X", cultureInfo)); + DepictInfo = e.Message; } catch (IOException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]端口处于无效状态", e.HResult.ToString("X", cultureInfo)); + DepictInfo = e.Message; } } #region 流控制 - public void NoneEnable() + internal void NoneEnable() { SerialPortModel.XOnXOffEnable = false; SerialPortModel.RequestToSendEnable = false; @@ -221,15 +224,15 @@ public void NoneEnable() } catch (IOException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]端口处于无效状态", e.HResult.ToString("X", cultureInfo)); + DepictInfo = e.Message; } catch (ArgumentOutOfRangeException e) { - DepictInfo = string.Format(cultureInfo, "设置流控制为{0}是非法操作", e.ParamName); + DepictInfo = e.Message; } } - public void RequestToSendEnable() + internal void RequestToSendEnable() { SerialPortModel.NoneEnable = false; SerialPortModel.XOnXOffEnable = false; @@ -246,15 +249,15 @@ public void RequestToSendEnable() } catch (IOException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]端口处于无效状态", e.HResult.ToString("X", cultureInfo)); + DepictInfo = e.Message; } catch (ArgumentOutOfRangeException e) { - DepictInfo = string.Format(cultureInfo, "设置流控制为{0}是非法操作", e.ParamName); + DepictInfo = e.Message; } } - public void XOnXOffEnable() + internal void XOnXOffEnable() { SerialPortModel.NoneEnable = false; SerialPortModel.RequestToSendEnable = false; @@ -271,15 +274,15 @@ public void XOnXOffEnable() } catch (IOException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]端口处于无效状态", e.HResult.ToString("X", cultureInfo)); + DepictInfo = e.Message; } catch (ArgumentOutOfRangeException e) { - DepictInfo = string.Format(cultureInfo, "设置流控制为{0}是非法操作", e.ParamName); + DepictInfo = e.Message; } } - public void RequestToSendXOnXOffEnable() + internal void RequestToSendXOnXOffEnable() { SerialPortModel.NoneEnable = false; SerialPortModel.XOnXOffEnable = false; @@ -296,17 +299,17 @@ public void RequestToSendXOnXOffEnable() } catch (IOException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]端口处于无效状态", e.HResult.ToString("X", cultureInfo)); + DepictInfo = e.Message; } catch (ArgumentOutOfRangeException e) { - DepictInfo = string.Format(cultureInfo, "设置流控制为{0}是非法操作", e.ParamName); + DepictInfo = e.Message; } } #endregion #region 发送换行 - public void NonesEnable() + internal void NonesEnable() { SendModel.CrEnable = false; SendModel.LfEnable = false; @@ -315,7 +318,7 @@ public void NonesEnable() SendModel.NonesEnable = true; } - public void CrEnable() + internal void CrEnable() { SendModel.NonesEnable = false; SendModel.LfEnable = false; @@ -324,7 +327,7 @@ public void CrEnable() SendModel.CrEnable = true; } - public void LfEnable() + internal void LfEnable() { SendModel.NonesEnable = false; SendModel.CrEnable = false; @@ -333,7 +336,7 @@ public void LfEnable() SendModel.LfEnable = true; } - public void CrLfEnable() + internal void CrLfEnable() { SendModel.NonesEnable = false; SendModel.CrEnable = false; @@ -346,7 +349,7 @@ public void CrLfEnable() #endregion #region 视图 - public void ReducedEnable() + internal void ReducedEnable() { HelpModel.ReducedEnable = !HelpModel.ReducedEnable; @@ -362,19 +365,19 @@ public void ReducedEnable() #endregion #region 帮助 - public async void UpdateAsync() + internal async void UpdateAsync() { var _ReleaseDeserializer = new DataContractJsonSerializer(typeof(GitRelease)); - GitRelease _ReleaseGit = await - DownloadJsonObjectAsync(GitReleaseBase.GithubURI, _ReleaseDeserializer, "github").ConfigureAwait(false); + GitRelease _ReleaseGit = await DownloadJsonObjectAsync( + GitReleaseBase.GithubURI, _ReleaseDeserializer, "github").ConfigureAwait(false); if (_ReleaseGit == default) { DepictInfo = string.Format(cultureInfo, "更换服务器......请稍后"); - _ReleaseGit = await - DownloadJsonObjectAsync(GitReleaseBase.GiteeURI, _ReleaseDeserializer, "gitee").ConfigureAwait(false); + _ReleaseGit = await DownloadJsonObjectAsync( + GitReleaseBase.GiteeURI, _ReleaseDeserializer, "gitee").ConfigureAwait(false); if (_ReleaseGit == default) { @@ -387,7 +390,7 @@ public async void UpdateAsync() UpdateVersionCompareTo(_ReleaseGit.GetVersion()); } - protected async Task DownloadJsonObjectAsync(Uri address, DataContractJsonSerializer serializer, string git) + private protected async Task DownloadJsonObjectAsync(Uri address, DataContractJsonSerializer serializer, string git) { if(serializer == null) { @@ -421,8 +424,22 @@ protected async Task DownloadJsonObjectAsync(Uri address, DataContractJson } } } - catch + catch(ArgumentException e) + { + DepictInfo = e.Message; + + return default; + } + catch(HttpRequestException e) { + DepictInfo = e.Message; + + return default; + } + catch(TaskCanceledException e) + { + DepictInfo = e.Message; + return default; } } @@ -457,11 +474,13 @@ private void ThreadStartingWPFUpdate() #endregion #region 打开/关闭串口 - public bool OpenSP() + internal void OpenSP() { - if (SerialPortBase != null && SerialPortBase.IsOpen) + if (SerialPortBase.IsOpen) { - return CloseSP(); + CloseSP(); + + return; } try @@ -564,83 +583,60 @@ public bool OpenSP() { RecvModel.RecvEnable = string.Format(cultureInfo, "暂停"); } - - return true; } else { DepictInfo = string.Format(cultureInfo, "串行端口打开失败"); - - return false; } } catch (UnauthorizedAccessException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]端口访问被拒绝", e.HResult.ToString("X", cultureInfo)); - - return false; + DepictInfo = e.Message; } catch (ArgumentOutOfRangeException e) { - DepictInfo = string.Format(cultureInfo, "串口属性{0}是非法的", e.ParamName); - - return false; + DepictInfo = e.Message; } catch (ArgumentException e) { - DepictInfo = string.Format(cultureInfo, "串口{0}不支持", e.ParamName); - - return false; + DepictInfo = string.Format(cultureInfo, "串行端口属性{0}为非法参数,请重新输入", e.ParamName); } catch (IOException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]端口处于无效状态", e.HResult.ToString("X", cultureInfo)); - - return false; + DepictInfo = e.Message; } catch (InvalidOperationException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]指定端口已经打开", e.HResult.ToString("X", cultureInfo)); - - return false; + DepictInfo = e.Message; } } - public bool CloseSP() + private void CloseSP() { try { - if (SerialPortBase.IsOpen) - { - SerialPortBase.Close(); - - SerialPortModel.SPBrush = Brushes.Red; - SerialPortModel.OpenCloseSP = string.Format(cultureInfo, "打开串口"); - - DepictInfo = string.Format(cultureInfo, "串行端口关闭成功"); + /* + * 该方法调用Component.Dispose()方法,同时还会 + * 调用disposing参数设置为True的受保护的SerialPort.Dispose(Boolean)方法 + */ + SerialPortBase.Close(); /* 关闭SerialPort对象,并清除接收缓冲区和发送缓冲区 */ - SerialPortModel.SPPortEnable = true; - SerialPortModel.SPBaudRateEnable = true; - SerialPortModel.SPDataBitsEnable = true; - SerialPortModel.SPStopBitsEnable = true; - SerialPortModel.SPParityEnable = true; + SerialPortModel.SPBrush = Brushes.Red; + SerialPortModel.OpenCloseSP = string.Format(cultureInfo, "打开串口"); - RecvModel.RecvAutoSave = string.Format(cultureInfo, "已停止"); + DepictInfo = string.Format(cultureInfo, "串行端口关闭成功"); - return SerialPortBase.IsOpen; - } - else - { - DepictInfo = string.Format(cultureInfo, "串行端口已关闭"); + SerialPortModel.SPPortEnable = true; + SerialPortModel.SPBaudRateEnable = true; + SerialPortModel.SPDataBitsEnable = true; + SerialPortModel.SPStopBitsEnable = true; + SerialPortModel.SPParityEnable = true; - return SerialPortBase.IsOpen; - } + RecvModel.RecvAutoSave = string.Format(cultureInfo, "已停止"); } catch(IOException e) { - DepictInfo = string.Format(cultureInfo, "[{0}]端口处于无效状态", e.HResult.ToString("X", cultureInfo)); - - return false; + DepictInfo = e.Message; } } #endregion @@ -663,11 +659,11 @@ public bool SaveRecv if (SaveRecv) { - DepictInfo = "接收数据默认保存在程序基目录,可以点击路径选择操作更换"; + DepictInfo = string.Format(cultureInfo, "接收数据默认保存在程序基目录,可以点击路径选择操作更换"); } else { - DepictInfo = "串行端口调试助手"; + DepictInfo = string.Format(cultureInfo, "串行端口调试助手"); } } } @@ -707,14 +703,7 @@ public bool AutoSend } set { - if (SerialPortBase == null) - { - DepictInfo = string.Format(cultureInfo, "串行端口资源异常,建议重启计算机"); - - return; - } - - if (SerialPortBase.IsOpen == false) + if (!SerialPortBase.IsOpen) { DepictInfo = string.Format(cultureInfo, "请先打开串行端口"); @@ -774,16 +763,9 @@ private void StopAutoSendTimer() #endregion #region 发送 - public async Task SendAsync() + internal async Task SendAsync() { - if (SerialPortBase == null) - { - DepictInfo = string.Format(cultureInfo, "串行端口资源异常,建议重启计算机"); - - return; - } - - if (SerialPortBase.IsOpen == false) + if (!SerialPortBase.IsOpen) { DepictInfo = string.Format(cultureInfo, "请先打开串行端口"); @@ -838,24 +820,41 @@ await SerialPortBase.BaseStream.WriteAsync(SerialPortBase.Encoding.GetBytes("\r\ SendModel.SendDataCount += (SendCount + 2); } } - catch + catch (ArgumentException e) { - DepictInfo = string.Format(cultureInfo, "发送异常,请检查发送数据"); + DepictInfo = e.Message; + } + catch (IOException e) + { + DepictInfo = e.Message; + } + catch (OutOfMemoryException e) + { + DepictInfo = e.Message; + } + catch (FormatException e) + { + DepictInfo = e.Message; + } + catch (IndexOutOfRangeException) + { + DepictInfo = string.Format(cultureInfo, "正在试图执行越界访问,请通过菜单栏<帮助>报告问题!"); + } + catch (NotFiniteNumberException e) + { + DepictInfo = e.Message; + } + catch (ObjectDisposedException) + { + DepictInfo = string.Format(cultureInfo, "正在对已释放的对象执行操作,请通过菜单栏<帮助>报告问题!"); } } #endregion #region 发送文件 - public async Task SendFileAsync() + internal async Task SendFileAsync() { - if (SerialPortBase == null) - { - DepictInfo = string.Format(cultureInfo, "串行端口资源异常,建议重启计算机"); - - return; - } - - if (SerialPortBase.IsOpen == false) + if (!SerialPortBase.IsOpen) { DepictInfo = string.Format(cultureInfo, "请先打开串行端口"); @@ -904,15 +903,39 @@ await SerialPortBase.BaseStream.WriteAsync(SerialPortBase.Encoding.GetBytes(file HelpModel.StatusBarProgressBarVisibility = "Collapsed"; } } - catch + catch(ArgumentException e) + { + DepictInfo = e.Message; + } + catch(IOException e) + { + DepictInfo = e.Message; + } + catch(OutOfMemoryException e) { - DepictInfo = string.Format(cultureInfo, "文件发送失败,请重新尝试!"); + DepictInfo = e.Message; + } + catch(FormatException e) + { + DepictInfo = e.Message; + } + catch(IndexOutOfRangeException) + { + DepictInfo = string.Format(cultureInfo, "正在试图执行越界访问,请通过菜单栏<帮助>报告问题!"); + } + catch(NotFiniteNumberException e) + { + DepictInfo = e.Message; + } + catch(ObjectDisposedException) + { + DepictInfo = string.Format(cultureInfo, "正在对已释放的对象执行操作,请通过菜单栏<帮助>报告问题!"); } } #endregion #region 路径选择 - public void SaveRecvPath() + internal void SaveRecvPath() { SaveFileDialog ReceDataSaveFileDialog = new SaveFileDialog { @@ -930,7 +953,7 @@ public void SaveRecvPath() #endregion #region 清接收区 - public void ClarReceData() + internal void ClarReceData() { RecvModel.RecvData.Delete(); @@ -939,14 +962,14 @@ public void ClarReceData() #endregion #region 清发送区 - public void ClearSendData() + internal void ClearSendData() { SendModel.SendData = string.Empty; } #endregion #region 清空计数 - public void ClearCount() + internal void ClearCount() { RecvModel.RecvDataCount = 0; SendModel.SendDataCount = 0; @@ -954,7 +977,7 @@ public void ClearCount() #endregion #region 数据接收事件实现 - public async void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) + private async void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) { if ((SerialPort)sender == null) { @@ -1004,7 +1027,7 @@ public async void SerialPortDataReceived(object sender, SerialDataReceivedEventA } } - public async void SaveRecvData(string ReceData) + private async void SaveRecvData(string ReceData) { try { @@ -1028,17 +1051,67 @@ public async void SaveRecvData(string ReceData) } } } - catch + catch(IOException e) { + SaveRecv = false; RecvModel.RecvAutoSave = string.Format(cultureInfo, "已停止"); - DepictInfo = string.Format(cultureInfo, "接收数据保存失败"); + DepictInfo = e.Message; + } + catch(ArgumentException e) + { + SaveRecv = false; + RecvModel.RecvAutoSave = string.Format(cultureInfo, "已停止"); + + DepictInfo = e.Message; + } + catch(UnauthorizedAccessException e) + { + SaveRecv = false; + RecvModel.RecvAutoSave = string.Format(cultureInfo, "已停止"); + + DepictInfo = e.Message; + } + catch(NotSupportedException e) + { + SaveRecv = false; + RecvModel.RecvAutoSave = string.Format(cultureInfo, "已停止"); + + DepictInfo = e.Message; + } + catch (IndexOutOfRangeException) + { + SaveRecv = false; + RecvModel.RecvAutoSave = string.Format(cultureInfo, "已停止"); + + DepictInfo = string.Format(cultureInfo, "正在试图执行越界访问,请通过菜单栏<帮助>报告问题!"); + } + catch (ObjectDisposedException) + { + SaveRecv = false; + RecvModel.RecvAutoSave = string.Format(cultureInfo, "已停止"); + + DepictInfo = string.Format(cultureInfo, "正在对已释放的对象执行操作,请通过菜单栏<帮助>报告问题!"); + } + catch (AppDomainUnloadedException) + { + SaveRecv = false; + RecvModel.RecvAutoSave = string.Format(cultureInfo, "已停止"); + + DepictInfo = string.Format(cultureInfo, "正在访问已卸载的应用程序域,请通过菜单栏<帮助>报告问题!"); + } + catch(System.Security.SecurityException e) + { + SaveRecv = false; + RecvModel.RecvAutoSave = string.Format(cultureInfo, "已停止"); + + DepictInfo = e.Message; } } #endregion #region 信号状态事件实现 - public void SerialPortPinChanged(object sender, SerialPinChangedEventArgs e) + private void SerialPortPinChanged(object sender, SerialPinChangedEventArgs e) { if((SerialPort)sender == null) { @@ -1091,17 +1164,17 @@ public void SerialPortPinChanged(object sender, SerialPinChangedEventArgs e) #endregion #region RecvTextBox Mouse Double Support - public void EnableRecv() + internal void EnableRecv() { RecvModel.EnableRecv = !RecvModel.EnableRecv; if(RecvModel.EnableRecv) { - RecvModel.RecvEnable = "允许"; + RecvModel.RecvEnable = string.Format(cultureInfo, "允许"); } else { - RecvModel.RecvEnable = "暂停"; + RecvModel.RecvEnable = string.Format(cultureInfo, "暂停"); } } #endregion @@ -1132,35 +1205,40 @@ public MainWindowViewModel() } #region IDisposable Support - private bool disposedValue = false; + private bool disposedValue = false; /* 冗余检测 */ /// - /// 受保护的 Dispose 方法实现 + /// 释放组件所使用的非托管资源,并且有选择的释放托管资源(可以看作是Dispose()的安全实现) /// /// protected virtual void Dispose(bool disposing) { + /* 检查是否已调用dispose */ if (!disposedValue) { if (disposing) { - /* 释放托管资源(如果需要) */ + /* 释放托管资源(如果需要的话) */ + + /* SerialPort属于托管资源,但其本身却拥有非托管资源,所以需要实现IDisposable */ + SerialPortBase.DataReceived -= SerialPortDataReceived; + SerialPortBase.PinChanged -= SerialPortPinChanged; + SerialPortBase.Dispose(); } - SerialPortBase.Dispose(); - SerialPortBase = null; + /* 释放非托管资源(如果有的话) */ - disposedValue = true; + disposedValue = true; /* 处理完毕 */ } } /// - /// SerialPort 字段 IDisposable 接口的 Dispose 方法实现(无参数) + /// 实现IDisposable,释放组件所使用的所有资源 /// public void Dispose() { Dispose(true); - GC.SuppressFinalize(this); + GC.SuppressFinalize(this); /* this: OSDA.ViewModels.MainWindowViewmodel */ } #endregion } diff --git a/Views/MainWindow.xaml b/Views/MainWindow.xaml index 0c52a3b..e9345a8 100644 --- a/Views/MainWindow.xaml +++ b/Views/MainWindow.xaml @@ -140,7 +140,7 @@ Style="{StaticResource SBStatusBarItem}"/> - + diff --git a/Views/MainWindow.xaml.cs b/Views/MainWindow.xaml.cs index 0ac370b..ebd6e4c 100644 --- a/Views/MainWindow.xaml.cs +++ b/Views/MainWindow.xaml.cs @@ -1,5 +1,6 @@ using OSDA.Interfaces; using OSDA.ViewModels; +using System; using System.Diagnostics; using System.Windows; using System.Windows.Controls; @@ -7,9 +8,9 @@ namespace OSDA.Views { - public partial class MainWindow : Window + public partial class MainWindow : Window, IDisposable { - private readonly MainWindowViewModel mainWindowViewModel = null; + internal MainWindowViewModel mainWindowViewModel = null; public MainWindow() { @@ -291,6 +292,42 @@ private void RecvTextBox_TextChanged(object sender, TextChangedEventArgs e) RecvTextBox.ScrollToEnd(); } #endregion + + #region IDisposable Support + private bool disposedValue = false; /* 冗余检测 */ + + /// + /// 释放组件所使用的非托管资源,并且有选择的释放托管资源(可以看作是Dispose()的安全实现) + /// + /// + protected virtual void Dispose(bool disposing) + { + /* 检查是否已调用dispose */ + if (!disposedValue) + { + if (disposing) + { + /* 释放托管资源(如果需要) */ + + /* 由于mainWindowViewModel对象拥有SerialPort,因此间接拥有SerialPort的非托管资源,所以需要实现IDisposable */ + mainWindowViewModel.Dispose(); + } + + /* 释放非托管资源(如果有的话) */ + + disposedValue = true; /* 处理完毕 */ + } + } + + /// + /// 实现IDisposable,释放组件所使用的所有资源 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this);/* this: OSDA.Views.MainWindow */ + } + #endregion } #region RecvTextBox Append Text Support diff --git a/Views/WPFUpdate.xaml.cs b/Views/WPFUpdate.xaml.cs index cb94b05..bfbb944 100644 --- a/Views/WPFUpdate.xaml.cs +++ b/Views/WPFUpdate.xaml.cs @@ -9,7 +9,7 @@ namespace OSDA.Views /// public partial class WPFUpdate : Window { - private readonly WPFUpdateViewModel wPFUpdateViewModel = null; + internal WPFUpdateViewModel wPFUpdateViewModel = null; public WPFUpdate() {