C# 基于 Windows 系統與 Visual Studio 2017 的 Messenger 消息傳遞機制詳解:發布-訂閱模式實現

在這里插入圖片描述

🧑 博主簡介:CSDN博客專家、CSDN平臺優質創作者,高級開發工程師,數學專業,10年以上C/C++, C#, Java等多種編程語言開發經驗,擁有高級工程師證書;擅長C/C++、C#等開發語言,熟悉Java常用開發技術,能熟練應用常用數據庫SQL server,Oracle,mysql,postgresql等進行開發應用,熟悉DICOM醫學影像及DICOM協議,業余時間自學JavaScript,Vue,qt,python等,具備多種混合語言開發能力。撰寫博客分享知識,致力于幫助編程愛好者共同進步。歡迎關注、交流及合作,提供技術支持與解決方案。\n技術合作請加本人wx(注明來自csdn):xt20160813

在這里插入圖片描述

C# 基于 Windows 系統與 Visual Studio 2017 的 Messenger 消息傳遞機制詳解:發布-訂閱模式實現

在 C# 開發中,特別是在 Windows 平臺的客戶端應用程序開發中,Messenger 是一種基于發布-訂閱模式(Publish-Subscribe Pattern)的消息傳遞機制,廣泛應用于 MVVM(Model-View-ViewModel)架構,如 WPF 應用程序。它通過 Messenger.Default.SendMessenger.Default.Register 實現松耦合的模塊間通信,特別適合復雜 UI 交互和跨組件協作場景。本文基于 Windows 系統Visual Studio 2017,結合歷史對話中提到的代碼示例(如 Messenger.Default.Send<string>("Recovery", "fanxuan")),詳細解析 Messenger 的實現原理、配置環境、應用場景及完整代碼示例,確保內容準確、具體且可直接應用于 Windows 開發。


一、引言

在 Windows 平臺的 C# 開發中,MVVM 架構常用于構建可維護、可測試的應用程序。Messenger 作為 MVVM 框架(如 MVVM Light、Prism)的核心組件,通過發布-訂閱模式實現模塊間通信,避免直接耦合。歷史對話中的代碼展示了 Messenger 在醫學影像系統(DICOM 相關)中用于觸發恢復按鈕狀態的場景,例如通過 ESC 鍵發送 "Recovery" 消息。本文將從 Windows 系統和 Visual Studio 2017 的開發環境出發,深入剖析 Messenger 的工作機制,提供配置指南、完整代碼示例,并結合實際應用場景(如 UI 狀態恢復)進行說明。


二、發布-訂閱模式與 Messenger 概述

1. 發布-訂閱模式

發布-訂閱模式是一種解耦設計模式,核心組件包括:

  • 發布者(Publisher):發送消息,不關心接收者。
  • 訂閱者(Subscriber):注冊對特定消息的興趣,處理接收到的消息。
  • 消息中介(Broker):管理消息分發,通過消息類型或令牌(Token)過濾。

優點

  • 松耦合:模塊間無需直接引用,降低依賴。
  • 一對多通信:支持多個訂閱者處理同一消息。
  • 線程安全:結合 Windows 的 Dispatcher 機制,確保 UI 操作在主線程執行。
2. Messenger 的功能

Messenger 是 MVVM 框架(如 MVVM Light)提供的消息傳遞工具,核心方法包括:

  • 發送消息Messenger.Default.Send<T>(message, token),發送類型為 T 的消息,可指定令牌 token
  • 注冊訂閱Messenger.Default.Register<T>(recipient, token, action),注冊處理特定類型和令牌的消息。
  • 令牌機制:通過 token(如字符串 "fanxuan")實現定向消息傳遞。
  • 線程支持:結合 WPF 的 Dispatcher 確保線程安全。

在歷史對話中,Messenger.Default.Send<string>("Recovery", "fanxuan") 用于發送恢復命令,目標是注冊了 "fanxuan" 令牌的訂閱者,通常用于 UI 狀態重置或 DICOM 數據操作。


三、Windows 系統與 Visual Studio 2017 環境配置

1. 系統與工具要求
  • 操作系統:Windows 10(推薦 64 位,支持 Visual Studio 2017)。
  • 開發工具:Visual Studio 2017(Community、Professional 或 Enterprise 版本)。
  • 框架:.NET Framework 4.6.1 或更高版本(WPF 項目常用)。
  • NuGet 包:MVVM Light(MvvmLightLibs)。
2. 配置 MVVM Light

在 Visual Studio 2017 中安裝 MVVM Light:

  1. 打開 NuGet 包管理器
    • 在 Visual Studio 2017 中,點擊 工具 > NuGet 包管理器 > 管理解決方案的 NuGet 包
  2. 搜索并安裝 MVVM Light
    • 搜索 MvvmLightLibs,選擇 GalaSoft.MvvmLight,點擊 安裝
    • 安裝完成后,項目引用中將包含 GalaSoft.MvvmLight.dll
  3. 驗證環境
    • 創建一個 WPF 項目,添加以下 using 語句:
      using GalaSoft.MvvmLight;
      using GalaSoft.MvvmLight.Messaging;
      
    • 確保無編譯錯誤。
3. 項目設置
  • 創建 WPF 項目
    • 在 Visual Studio 2017 中,選擇 文件 > 新建 > 項目 > Visual C# > Windows 經典桌面 > WPF 應用
    • 項目命名為 MessengerDemo
  • 添加 ViewModel
    • 創建 ViewModels 文件夾,添加 MainViewModel.csButtonViewModel.cs
  • 配置 Dispatcher
    • WPF 項目默認包含 Dispatcher,無需額外配置。若需自定義 Dispatcher,可使用 Application.Current.Dispatcher

四、Messenger 的核心方法

1. Messenger.Default.Send

簽名

void Send<T>(T message, object token = null);
  • 參數
    • message:消息內容(如字符串 "Recovery")。
    • token:可選的令牌,用于過濾接收者(如 "fanxuan")。
  • 作用:將消息廣播給匹配 token 和類型 T 的訂閱者。
  • 示例
    Messenger.Default.Send<string>("Recovery", "fanxuan");
    
2. Messenger.Default.Register

簽名

void Register<T>(object recipient, object token, Action<T> action);
  • 參數
    • recipient:訂閱者對象(通常為 this)。
    • token:與發送端匹配的令牌。
    • action:收到消息后的回調函數。
  • 作用:注冊處理特定類型和令牌的消息。
  • 示例
    Messenger.Default.Register<string>(this,"fanxuan",message => { /* 處理邏輯 */ }
    );
    
3. 消息傳遞流程
graph LRA[Send: Messenger.Default.Send<string>("Recovery", "fanxuan")] --> B[Messenger 中介]B --> C[查找匹配 "fanxuan" 和 string 的訂閱者]C --> D[Register: Messenger.Default.Register<string>(this, "fanxuan", ...)]D --> E[執行回調: Dispatcher.Invoke(button1_Click)]

五、Messenger 實現原理

Messenger 基于單例模式(Messenger.Default),內部維護訂閱者列表。核心邏輯包括:

  1. 訂閱管理
    • Register 方法將 {recipient, token, action} 存儲在字典中,鍵為消息類型 Ttoken
  2. 消息分發
    • Send 方法遍歷訂閱者列表,匹配 Ttoken,調用對應的 action
  3. 線程安全
    • 在 WPF 中,Dispatcher.Invoke 確保 UI 操作在主線程執行。
  4. 令牌匹配
    • 令牌通過 Equals 方法比較(如字符串的哈希比較),實現高效過濾。

六、Messenger 在歷史對話中的應用

歷史對話中的代碼展示了 Messenger 在醫學影像系統中的應用,用于觸發 UI 恢復:

發送端
case ItCallBackMSG.Recovery: // 通過 ESC 鍵觸發恢復
{Messenger.Default.Send<string>("Recovery", "fanxuan");break;
}
  • 場景:用戶按 ESC 鍵觸發 ItCallBackMSG.Recovery,發送 "Recovery" 消息到 "fanxuan" 通道。
  • 目的:通知訂閱者執行 UI 按鈕狀態恢復或 DICOM 數據重置。
接收端
Messenger.Default.Register<string>(this,"fanxuan",message => DcmOperateDispatcher.Invoke(new Onclick(button1_Click), null, null)
);
  • 場景:某個類(可能是 ViewModel 或 View)注冊 "fanxuan" 通道,收到消息后調用 button1_Click
  • 線程安全DcmOperateDispatcher.Invoke 確保回調在 UI 線程執行。
  • 改進建議:添加消息內容判斷(如 if (message == "Recovery"))以提高特異性。

七、完整代碼示例

以下是一個基于 WPF 的完整示例,展示 Messenger 在 Windows 系統中的應用,模擬 ESC 鍵觸發按鈕狀態恢復。

1. 項目結構
  • MainWindow.xaml:主窗口,包含一個按鈕。
  • MainViewModel.cs:發送恢復消息。
  • ButtonViewModel.cs:接收消息并處理按鈕狀態。
2. XAML(MainWindow.xaml)
<Window x:Class="MessengerDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="Messenger Demo" Height="200" Width="300"><Grid><Button Content="Recover State" Width="100" Height="30"Command="{Binding RecoverCommand}"/></Grid>
</Window>
3. MainViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;public class MainViewModel : ViewModelBase
{public RelayCommand RecoverCommand { get; private set; }public MainViewModel(){// 初始化命令,模擬 ESC 鍵觸發RecoverCommand = new RelayCommand(SendRecoveryCommand);}private void SendRecoveryCommand(){// 發送恢復消息到 "fanxuan" 通道Messenger.Default.Send<string>("Recovery", "fanxuan");}
}
4. ButtonViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
using System.Windows;public class ButtonViewModel : ViewModelBase
{public ButtonViewModel(){// 注冊 "fanxuan" 通道的消息Messenger.Default.Register<string>(this,"fanxuan",message =>{if (message == "Recovery"){// 在 UI 線程執行恢復邏輯Application.Current.Dispatcher.Invoke(() =>{RecoverButtonState();});}});}private void RecoverButtonState(){// 模擬恢復按鈕狀態MessageBox.Show("Button state recovered!");// 實際邏輯:重置 UI 或 DICOM 數據}
}
5. 主程序(App.xaml.cs)
using GalaSoft.MvvmLight.Messaging;
using System.Windows;public partial class App : Application
{protected override void OnStartup(StartupEventArgs e){base.OnStartup(e);// 初始化 ViewModelvar mainViewModel = new MainViewModel();var buttonViewModel = new ButtonViewModel();// 設置主窗口var mainWindow = new MainWindow{DataContext = mainViewModel};mainWindow.Show();}
}
6. 運行結果
  • 點擊窗口中的“Recover State”按鈕,觸發 RecoverCommand,發送 "Recovery" 消息。
  • ButtonViewModel 捕獲消息,顯示提示框“Button state recovered!”。
  • 實際應用中,可在 RecoverButtonState 中實現 UI 重置或 DICOM 數據恢復邏輯。

八、在 Windows 系統中的開發注意事項

  1. Visual Studio 2017 配置

    • 確保安裝 .NET Framework 4.6.1 或更高版本。
    • 使用 NuGet 包管理器安裝 MvvmLightLibs(版本 5.4.1 兼容 VS2017)。
    • 若網絡受限,可下載離線 NuGet 包:
      nuget install MvvmLightLibs -Version 5.4.1 -OutputDirectory .\Packages
      
  2. 調試技巧

    • 在 Visual Studio 2017 中設置斷點,檢查 Messenger.Default.SendRegister 的執行流程。
    • 使用 即時窗口查看 Messenger 訂閱者列表(需自定義 Messenger 實現)。
    • 驗證 Dispatcher.Invoke 是否正確切換到 UI 線程。
  3. 性能優化

    • 避免頻繁注冊/注銷訂閱者,建議在 ViewModel 構造時注冊,析構時注銷:
      public override void Cleanup()
      {Messenger.Default.Unregister(this);base.Cleanup();
      }
      
    • 使用具體 token(如 "fanxuan")減少消息廣播開銷。
  4. DICOM 集成

    • 在醫學影像系統中,Messenger 可用于通知 UI 更新 DICOM 參數(如 FOV、TR)。
    • 示例:發送 DICOM 文件加載完成消息:
      Messenger.Default.Send<string>("DICOMLoaded", "fanxuan");
      

九、常見問題與解決方案

問題解決方案
消息未被接收確認 SendRegistertoken 和消息類型一致。
UI 更新失敗使用 Application.Current.Dispatcher.Invoke 確保回調在 UI 線程執行。
NuGet 安裝失敗離線下載 MvvmLightLibs 包,導入項目:nuget install MvvmLightLibs
消息誤觸發Register 的回調中添加條件判斷:if (message == "Recovery")

十、總結

Messenger.Default.SendMessenger.Default.Register 是 C# 中基于發布-訂閱模式的強大消息傳遞機制,特別適合 Windows 平臺的 WPF 開發。基于 Visual Studio 2017 環境,本文提供了完整的配置指南和代碼示例,展示了 Messenger 在 UI 狀態恢復(如歷史對話中的 ESC 鍵觸發)中的應用。核心特點:

  1. 松耦合:通過 token 實現定向通信。
  2. 線程安全:結合 Dispatcher 確保 UI 操作安全。
  3. 易用性:MVVM Light 提供簡單 API,適合快速開發。

在 Windows 系統和 Visual Studio 2017 中,開發者可通過 NuGet 快速集成 MVVM Light,結合 WPF 的 Dispatcher 機制實現高效通信。建議在實際開發中添加消息內容驗證和訂閱者管理,以提高代碼健壯性。


參考資料

  • MVVM Light 文檔:http://www.mvvmlight.net/
  • Visual Studio 2017 文檔:https://docs.microsoft.com/en-us/visualstudio/
  • C# 委托與事件:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/events/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/85267.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85267.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85267.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

js數據類型有哪些?它們有什么區別?

js數據類型共有8種,分別是undefined,null,boolean,number,string,Object,symbol,bigint symbol和bigint是es6中提出來的數據類型 symbol創建后獨一無二不可變的數據類型,它主要是為了解決出現全局變量沖突的問題 bigint 是一種數字類型的數據,它可以表示任意精度格式的整數,…

Vite打包優化實踐:從分包到性能提升

前言: ??????? 隨著前端應用功能的增加&#xff0c;項目的打包體積也會不斷膨脹&#xff0c;影響加載速度和用戶體驗。本文介紹了幾種常見的打包優化策略&#xff0c;通過Vite和相關插件&#xff0c;幫助減少項目體積、提升性能&#xff0c;優化加載速度。 rollup-plugi…

C++語法系列之模板進階

前言 本次會介紹一下非類型模板參數、模板的特化(特例化)和模板的可變參數&#xff0c;不是最開始學的模板 一、非類型模板參數 字面意思,比如&#xff1a; template<size_t N 10> 或者 template<class T,size_t N 10>比如&#xff1a;靜態棧就可以用到&#…

html5的響應式布局的方法示例詳解

以下是HTML5實現響應式布局的5種核心方法及代碼示例: 1. 媒體查詢(核心方案) /* 默認樣式(移動優先) */ .container {padding: 15px; }/* 中等屏幕(平板) */ @media (min-width: 768px) {.container {padding: 30px;max-width: 720px;} }/* 大屏幕(桌面) */ @media …

數字化轉型進階:精讀41頁華為數字化轉型實踐【附全文閱讀】

該文檔聚焦華為數字化轉型實踐&#xff0c;核心內容如下&#xff1a; 轉型本質與目標&#xff1a;數字化轉型是通過數字技術穿透業務&#xff0c;實現物理世界與數字世界的融合&#xff0c;目標是支撐主業成功、提升體驗與效率、探索模式創新。華為以 “平臺 服務” 為核心&am…

C++ - STL #什么是STL #STL的版本 #閉源開源 #STL的六大組件

文章目錄 前言 一、什么是STL 二、STL的版本 1、原始版本 2、P.J.版本 3、RW版本 4、SGI版本 三、閉源、開源 四、STL的六大組件 總結 前言 路漫漫其修遠兮&#xff0c;吾將上下而求索&#xff1b; 一、什么是STL STL(standard template libaray 標準模板庫)&#…

智慧康養護理:科技重塑老齡化社會的健康守護體系

在我國邁入深度老齡化社會的背景下&#xff0c;智慧康養護理作為融合科技與人文的創新模式&#xff0c;正成為提升老年人生活質量、減輕家庭照護壓力、促進健康老齡化的重要路徑。我們將從核心概念、關鍵技術、實際應用與未來趨勢四個維度&#xff0c;為您呈現智慧康養護理的全…

權威認證與質量保障:第三方檢測在科技成果鑒定測試中的核心作用

科技成果鑒定測試是衡量科研成果技術價值與應用潛力的關鍵環節&#xff0c;其核心目標在于通過科學驗證確保成果的可靠性、創新性和市場適配性。第三方檢測機構憑借其獨立性、專業性和權威性&#xff0c;成為科技成果鑒定測試的核心支撐主體。本文從測試流程、第三方檢測的價值…

Linux.docker.k8s基礎概念

1.Linux基本命令 cat 查看文件內容。 cd 進入目標目錄。 ll 查詢當前路勁下文件的詳細信息。 ls 查詢當前路勁下的文件。 touch 建立一個文件。 mkdir 建立一個文件夾。 rm 刪除文件或者目錄。 mv 移動目錄和重新命名文件。 unzip 解壓。 top 查看當前線程的信息。 find …

Python小白的蛻變之旅:從環境搭建到代碼規范(1/10)

摘要&#xff1a;全文圍繞 Python 編程展開&#xff0c;先是介紹如何搭建 Python 開發環境&#xff0c;推薦使用 Anaconda 和 VSCode&#xff0c;并詳細說明了二者的安裝及配置步驟&#xff0c;包括安裝 Anaconda、安裝 VSCode 并配置 Python 插件、選擇 Anaconda 的 Python 解…

linux 1.0.7

用戶和權限的含義與作用 linux中的用戶和文件 用戶的權限是非常重要的 而且有些程序需要使用管理員身份去執行 這些都是非常重要的 不可能讓所有的人擁有所有的權限 這樣的工具可以避免非法的手段來修改計算機中的數據 linux之所以安全還是權限管理做的很棒 每個登錄的用戶都有…

【第4章 圖像與視頻】4.6 結合剪輯區域來繪制圖像

文章目錄 前言示例 前言 本節將綜合運用圖像處理、離屏 canvas 以及剪輯區域等技術實現墨鏡效果。 示例 主線程代碼&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport&qu…

UV 包管理工具:替代 pip 的現代化解決方案

安裝 方法一&#xff1a;使用安裝腳本 # macOS 和 Linux curl -LsSf https://astral.sh/uv/install.sh | sh# Windows PowerShell powershell -c "irm https://astral.sh/uv/install.ps1 | iex" 方法二&#xff1a;使用包管理器 # macOS (Homebrew) brew install uv#…

Java注解規范與使用詳解

注解中的空值限制 在Java注解中,元素值不允許使用null引用。這是注解使用中的一項重要約束規則,違反該規則將導致編譯錯誤。需要注意的是,雖然禁止使用null值,但允許為String類型元素指定空字符串(“”),為數組類型元素指定空數組({})。 空值約束示例 以下兩種注解用法…

從零開始的數據結構教程(八)位運算與狀態壓縮

&#x1f3a9; 標題一&#xff1a;位運算基礎——魔術師的二進制手套 位運算是一種直接操作數字二進制位的運算方式&#xff0c;它高效且巧妙&#xff0c;就像魔術師戴上了二進制手套&#xff0c;能夠精準地操控每一個比特。理解位運算是深入學習狀態壓縮和其他底層優化技巧的…

GraalVM加持下的Quarkus極速啟動

1. 引言 1.1 Quarkus與云原生時代的挑戰 隨著云原生架構的普及,傳統Java應用在部署效率、資源消耗和冷啟動性能方面逐漸暴露出短板。Spring Boot等框架雖然功能強大,但在Serverless、邊緣計算等場景下表現乏力。 Quarkus 是 Red Hat 推出的一個專為云原生設計的 Java/Kotl…

vue3 el-input type=“textarea“ 字體樣式 及高度設置

在Vue 3中&#xff0c;如果你使用的是Element Plus庫中的<el-input>組件作為文本域&#xff08;type"textarea"&#xff09;&#xff0c;你可以通過幾種方式來設置字體樣式和高度。 1. 直接在<el-input>組件上使用style屬性 你可以直接在<el-input&…

Matlab中gcb、gcbh、gcs的區別

gcb&#xff1a;返回當前選中模塊的完整路徑名&#xff08;字符串&#xff09; gcbh&#xff1a;返回當前選中模塊的句柄&#xff08;數值標識符&#xff09; gcs&#xff1a;返回當前打開或選中的子系統或頂層模型路徑&#xff08;字符串&#xff09;

大語言模型的技術原理與應用前景:從Transformer到ChatGPT

目錄 摘要 1. 引言 2. Transformer架構核心原理 2.1 自注意力機制 2.2 位置編碼 2.3 前饋神經網絡 3. 從GPT到ChatGPT的演進 3.1 GPT系列模型架構 3.2 訓練流程優化 4. 應用場景與案例分析 4.1 代碼生成 4.2 文本摘要 4.3 問答系統 5. 挑戰與未來方向 5.1 當前技…

Flink Table API 編程入門實踐

Flink Table API 編程入門實踐 前言 Apache Flink 是目前大數據實時計算領域的明星產品&#xff0c;Flink Table API 則為開發者提供了聲明式、類似 SQL 的數據處理能力&#xff0c;兼具 SQL 的易用性與編程 API 的靈活性。本文將帶你快速了解 Flink Table API 的基本用法&am…