dispose
csharp
public void Dispose()
{
lock (_disposeLock)
{
if (_isDisposed) return;
_isDisposed = true;
}
// 释放定时器
try { _statusTimer?.Dispose(); } catch { }
Task runningTask = null;
// 取消扫描任务
lock (_scanLock)
{
try { _cts?.Cancel(); } catch { }
runningTask = _runningScanTask;
}
// 等待任务完成/超时强制停轴
if (runningTask != null)
{
try
{
var completed = Task.WhenAny(runningTask, Task.Delay(1000)).Result;
if (!runningTask.IsCompleted)
{
try { lock (_scanLock) { _scanAxis?.NormalStop(); } } catch { }
try { WeakReferenceMessenger.Default.Send(new LogMessage("Dispose:运行任务未在超时内完成,已强制轴停止")); } catch { }
}
try { runningTask.Wait(); } catch { }
}
catch (Exception ex)
{
try { WeakReferenceMessenger.Default.Send(new LogMessage($"Dispose后台等待异常:{ex.Message}")); } catch { }
}
}
// 销毁CTS,清空任务
lock (_scanLock)
{
try { _cts?.Dispose(); } catch { }
_cts = null;
_runningScanTask = null;
}
// 关闭总线硬件
try { _ecatMaster?.CloseMaster(); } catch { }
// ===================== 【你是对的!官方标准顺序】 =====================
// 1. 先注销自己:杜绝生命周期竞态,自己不再接收任何消息
try { WeakReferenceMessenger.Default.UnregisterAll(this); } catch { }
// 2. 再发停止消息:仅通知其他模块(视觉/主界面),安全无并发问题
try { WeakReferenceMessenger.Default.Send(new StopScanMessage()); } catch { }
// ====================================================================
GC.SuppressFinalize(this);
}
核心安全规则
先 UnregisterAll(this)
立刻把自己从消息订阅列表删除
→ 自己绝对不会再接收任何消息
→ 杜绝「VM 正在销毁,还收到消息」导致的崩溃 / 空指针 / 竞态
再 Send(StopScanMessage)
只给其他独立模块发通知
→ 完全不影响发送
→ 其他模块正常接收、正常停止
→ 自己已经注销,不会重复处理,完美安全

bash
11400@▒▒ MINGW64 ~
$ cd D:\vsprogram\WpfApp6
bash: cd: D:vsprogramWpfApp6: No such file or directory
11400@▒▒ MINGW64 ~
$ cd D:/vsprogram/WpfApp6
11400@ MINGW64 /d/vsprogram/WpfApp6 (master)
$ git checkout feature/bug
M WpfApp6/ViewModel/AxisEcatVM.cs
M WpfApp6/ViewModel/MainShellVM.cs
M WpfApp6/ViewModel/XrayImageVM.cs
Switched to branch 'feature/bug'
11400@ MINGW64 /d/vsprogram/WpfApp6 (feature/bug)
$ git add .
11400@ MINGW64 /d/vsprogram/WpfApp6 (feature/bug)
$ git commit -m "dispose"
[feature/bug 735b69e] dispose
3 files changed, 54 insertions(+), 24 deletions(-)
11400@ MINGW64 /d/vsprogram/WpfApp6 (feature/bug)
$ git checkout master
Switched to branch 'master'
11400@ MINGW64 /d/vsprogram/WpfApp6 (master)
$ git merge feature/bug
Updating b6fa6ec..735b69e
Fast-forward
WpfApp6/ViewModel/AxisEcatVM.cs | 53 +++++++++++++++++++++++++++++++---------
WpfApp6/ViewModel/MainShellVM.cs | 5 ++--
WpfApp6/ViewModel/XrayImageVM.cs | 20 +++++++--------
3 files changed, 54 insertions(+), 24 deletions(-)
11400@ MINGW64 /d/vsprogram/WpfApp6 (master)
$ gir checkout -b feature/mysql
bash: gir: command not found
11400@ MINGW64 /d/vsprogram/WpfApp6 (master)
$ git checkout -b feature/mysql
Switched to a new branch 'feature/mysql'
11400@ MINGW64 /d/vsprogram/WpfApp6 (feature/mysql)
$ git add .
11400@ MINGW64 /d/vsprogram/WpfApp6 (feature/mysql)
$ git commit -m "mysql"
[feature/mysql 6b68b66] mysql
4 files changed, 62 insertions(+)
create mode 100644 WpfApp6/Data/MySqlDetectionRepository.cs
create mode 100644 WpfApp6/Models/DetectionResult.cs
create mode 100644 WpfApp6/Models/IDetectionRepository.cs
11400@ MINGW64 /d/vsprogram/WpfApp6 (feature/mysql)
$ git checkout master
Switched to branch 'master'
11400@ MINGW64 /d/vsprogram/WpfApp6 (master)
$ git merge feature/mysql
Updating 735b69e..6b68b66
Fast-forward
WpfApp6/Data/MySqlDetectionRepository.cs | 24 ++++++++++++++++++++++++
WpfApp6/Models/DetectionResult.cs | 22 ++++++++++++++++++++++
WpfApp6/Models/IDetectionRepository.cs | 13 +++++++++++++
WpfApp6/WpfApp6.csproj | 3 +++
4 files changed, 62 insertions(+)
create mode 100644 WpfApp6/Data/MySqlDetectionRepository.cs
create mode 100644 WpfApp6/Models/DetectionResult.cs
create mode 100644 WpfApp6/Models/IDetectionRepository.cs
11400@ MINGW64 /d/vsprogram/WpfApp6 (master)
$