WPF--Application.Current.Dispatcher.BeginInvoke

1.代碼示例

private void LogInfoList_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{// 直接在這里修改集合會引發遞歸if (e.Action == NotifyCollectionChangedAction.Add){if (logInfoList.Count > 200){logInfoList.RemoveAt(0); ?// 這里會觸發 CollectionChanged}}
}

修改為 `Dispatcher.BeginInvoke` 主要是為了避免在 `CollectionChanged` 事件處理程序中直接修改集合,導致遞歸調用的錯誤。`ObservableCollection` 會在修改時觸發 `CollectionChanged` 事件,因此如果在事件處理程序中再次修改該集合,事件會被重新觸發,這就可能導致無限遞歸或拋出錯誤。

具體原因和背景:

1. 避免遞歸調用:
? ?在 `CollectionChanged` 事件處理程序中直接修改集合會觸發另一次 `CollectionChanged` 事件。這樣就會進入遞歸調用的死循環,導致棧溢出或其他問題。

? ?
? ?例如,如果你在 `CollectionChanged` 中調用 `logInfoList.RemoveAt(0)`,這會導致 `logInfoList` 發生變化,從而再次觸發 `CollectionChanged` 事件,導致程序再次執行該事件處理程序。通過 `Dispatcher.BeginInvoke` 延遲操作,我們確保修改集合的操作會等到事件處理程序執行完后再執行,從而避免遞歸觸發事件。
2. UI 線程的調度:?
? ?`Dispatcher.BeginInvoke` 是用來在 UI 線程上執行任務的,它將操作推遲到下一個空閑時刻。即使你現在在處理事件,`Dispatcher.BeginInvoke` 也會讓 `logInfoList.RemoveAt(0)` 的調用等到當前事件處理程序完成后執行。這樣就不會發生集合修改時引發的事件觸發問題。
工作原理:

-Application.Current.Dispatcher.BeginInvoke(new Action(() => { ... }))` 是一個異步方法,它會在 UI 線程的消息隊列中排隊,并在當前事件處理程序(如 `CollectionChanged`)完成后執行傳入的操作。
- 這就確保了在執行 `RemoveAt(0)` 時不會再次觸發 `CollectionChanged` 事件,從而避免了遞歸調用的錯誤。

例子說明:

假設你有一個 `logInfoList`,并且在 `CollectionChanged` 中添加了移除第一個元素的邏輯。如果直接在事件中調用 `RemoveAt(0)`,則會觸發 `CollectionChanged`,導致無限循環:

private void LogInfoList_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{// 直接在這里修改集合會引發遞歸if (e.Action == NotifyCollectionChangedAction.Add){if (logInfoList.Count > 200){logInfoList.RemoveAt(0); ?// 這里會觸發 CollectionChanged}}
}

為了避免這個遞歸,我們通過 `Dispatcher.BeginInvoke` 延遲對集合的修改操作:

private void LogInfoList_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{if (e.Action == NotifyCollectionChangedAction.Add){// 使用 Dispatcher 來延遲移除第一個元素的操作Application.Current.Dispatcher.BeginInvoke(new Action(() =>{if (logInfoList.Count > 200){logInfoList.RemoveAt(0); ?// 這時不會觸發 CollectionChanged 事件}}));}
}

總結:
通過 `Dispatcher.BeginInvoke` 延遲集合的修改,能夠避免直接在事件處理過程中修改集合引發的遞歸調用問題,確保代碼能穩定運行。

事件遞歸問題補充:

問題核心: ?
當 `RemoveAt(0)` 執行時,確實會觸發一個新的 `CollectionChanged` 事件。由于使用了 `BeginInvoke` 延遲執行,所以這個新的事件處理程序會等當前的 `CollectionChanged` 事件處理完畢后才執行。那么,新的 `CollectionChanged` 事件在執行時會不會引發遞歸呢?

關鍵點:
1. 延遲執行的機制:
? ?使用 `Dispatcher.BeginInvoke` 延遲執行操作,它不會在當前事件處理過程中立刻執行。而是將操作推入到消息隊列中,待當前事件處理結束之后再執行。因此,新的 `CollectionChanged` 事件的處理程序 **不會在當前事件處理中執行**,也就是說,新的事件處理程序不會在遞歸的調用棧中。

2. 新的事件處理是否會遞歸:
? ?當新的 `CollectionChanged` 事件處理程序執行時,它會觸發一個新的事件,但是此時 **它已經不在當前事件的調用棧上。新的 `CollectionChanged` 事件是 **在當前事件完全結束后** 執行的,所以不會繼續遞歸回到同一個事件處理程序。

3. 為什么不會遞歸:
? ?遞歸的前提是事件在處理過程中不斷觸發新的事件,進入同一個事件處理程序。由于我們通過 `BeginInvoke` 延遲執行操作,新的事件觸發是在當前事件處理程序 **執行完后**,并且事件處理程序本身已經結束,所以 **新的事件不會重新進入相同的事件處理程序**,從而避免了遞歸

舉個例子:

void CollectionChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
{Console.WriteLine("Collection changed!");// 延遲刪除第一個元素Application.Current.Dispatcher.BeginInvoke(new Action(() =>{logInfoList.RemoveAt(0); ?// 刪除第一個元素}));
}

1. 第一次 `CollectionChanged` 事件觸發,進入 `CollectionChangedHandler`。
2. 在事件處理中,`BeginInvoke` 將 `RemoveAt(0)` 延遲執行,操作被排入消息隊列中。
3. 第一次 `CollectionChanged` 事件處理完畢后,`BeginInvoke` 中的 `RemoveAt(0)` 被執行,觸發新的 `CollectionChanged` 事件**。
4. 這個新的事件處理程序不會立即進入當前的 `CollectionChangedHandler`,因為當前事件處理已經結束。新的事件會等到當前的所有操作都完成后再執行。
5. 由于新的事件已經不在當前事件處理程序的上下文中,它不會再遞歸觸發。

?總結:
-新的 `CollectionChanged` 事件會被觸發,但它的事件處理程序會在當前事件處理程序完全執行完畢后才開始。
由于新的事件處理程序不在當前的事件處理上下文中,它不會再次進入同一個事件處理程序**,從而避免了遞歸。
?

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

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

相關文章

ZooKeeper詳解以及應用部署(AI)

ZooKeeper 是一個開源的分布式協調服務框架,旨在為分布式應用提供一致性保障和關鍵協調功能。其核心設計理念是將復雜的分布式一致性邏輯封裝為簡單可靠的接口,讓開發者專注于業務邏輯而非底層協調難題。以下是其核心要點: 🧠 一、…

將MySQL數據庫中所有表和字段編碼統一改為utf8mb4_unicode_ci

完整操作步驟 1. 首先修改數據庫默認字符集 sql ALTER DATABASE 你的數據庫名 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 2. 生成批量修改所有表的SQL語句 sql SELECT CONCAT(ALTER TABLE , table_schema, ., table_name, CONVERT TO CHARACTER SET utf8mb4 C…

jupyterhub的淺淺使用-重點在解決無法登錄

jupyterhub的淺淺使用-重點在解決無法登錄 jupyterhub的淺淺使用-重點在解決無法登錄1、jupyterhub是什么2、創建Dockerfile3、啟動容器3.1、生成配置文件jupyterhub --generate-config3.2、運行容器3.3、進入容器配置用戶密碼3.4、訪問127.0.0.1:8000并登錄 4、后臺創建的用戶…

【Bitcoin基礎】比特幣的地址格式有哪些?如何應用?

比特幣地址格式的分類及應用場景 比特幣地址是用于接收和發送比特幣的標識符,主要有以下幾種格式,每中類型都有其特定的用途和特點: 比特幣地址格式 P2PKH 1xxxx leagcy地址 P2SH 3xxxx 允許更復雜的交易多重簽名 bech32 bc1xxxx bech32mP2TR…

3.1.2_棧的順序存儲實現

知識總覽: 順序棧的定義: 順序棧是用順序存儲實現的 ,代碼定義方式和順序表類似(啥是順序表來著???) 定義一個順序棧struct結構體SqStack,結構體中有靜態數組data來存放棧里邊的元素1個int型的…

JavaEE初階第一期:計算機是如何 “思考” 的(上)

專欄:JavaEE初階起飛計劃 個人主頁:手握風云 一、馮諾依曼體系結構 1.1. 概念 馮諾依曼體系結構(Von Neumann Architecture),是現代計算機的基礎設計概念,核心思想是“存儲程序控制”。具體來說&#xff0c…

SQL Server全局搜索:在整個數據庫中查找特定值的高效方法

SQL Server全局搜索:在整個數據庫中查找特定值的高效方法 一、需求背景:為什么需要數據庫全局搜索? 在數據庫管理和開發過程中,我們經常會遇到這樣的場景: 只記得某個數據值,但忘記了它所在的表或列需要…

萬物皆數:構建數字信號處理的數學基石

萬物皆數:構建數字信號處理的數學基石 歡迎來到數字信號處理(DSP)的世界。在這里,聲音、圖像、通信信號、醫療數據……一切信息都被轉化為一串串冰冷的數字。然而,正是通過對這些數字的精妙運算,我們得以實…

到院率最高提升40%,消費醫療用AI營銷機器人跑贏增長焦慮

當前,消費醫療機構普遍依賴人工咨詢師進行客戶接待和營銷咨詢。然而,專業咨詢師缺口高達20萬人,大量“護士轉咨詢”“銷售轉咨詢”現象導致方案設計專業性不足,客戶投訴率提升40%。人工客服不僅醫學知識薄弱,學習能力有…

【推薦算法】注意力機制與興趣演化:推薦系統如何抓住用戶的心?

注意力機制與興趣演化:推薦系統如何抓住用戶的心? 一、算法背景知識:從靜態推薦到動態感知1.1 傳統推薦系統的局限性1.2 人類注意力機制的啟示 二、算法理論/結構:動態興趣建模革命2.1 DIN(深度興趣網絡)&a…

快速入門:創建 Azure 數據資源管理器群集和數據庫

前言 Azure 數據資源管理器是 Microsoft 提供的一項快速、完全托管的數據分析服務。 它允許用戶分析來自應用程序、網站、物聯網設備等的海量數據流,從而簡化復雜的數據探索。 它能夠處理數 PB 的數據,并支持快速檢索數據以進行分析。 主要特點 高性能:ADX 針對快速數據提…

Redis集群模式之Redis Cluster(2)

上篇文章我們講解了Redis Cluster中的主要模塊和兩種重定向方式,這篇文章我們來講解一下Redis Cluster的狀態監測和維護。 Redis Cluster狀態監測及維護 要講解Redis Cluster中節點的狀態如何維護,我們要先知道Redis Cluster中的節點有哪些狀態&#xf…

Step-Audio-AQAA 解讀:邁向「純語音」交互的端到端 LALM 新里程

引言:AI 從聽到說 大型音頻語言模型(Large Audio-Language Models, LALMs)正在徹底改變我們與機器交互的方式。我們不再滿足于簡單的文本問答,而是期望 AI 能夠像人類一樣,通過自然的語音進行交流,理解我們的意圖,并以富有表現力的聲音回應。然而,構建一個能夠直接從語…

基于邊緣計算的絲桿狀態實時監測系統設計?

基于邊緣計算的絲桿狀態實時監測系統設計,可從系統架構、各層功能設計、關鍵技術應用等方面入手,以下為詳細介紹: 系統架構設計 基于邊緣計算的絲桿狀態實時監測系統通常由感知層、邊緣層和云端三部分組成。感知層負責數據采集,…

LeetCode 每日一題 2025/6/9-2025/6/15

記錄了初步解題思路 以及本地實現代碼;并不一定為最優 也希望大家能一起探討 一起進步 目錄 6/9 440. 字典序的第K小數字6/10 3442. 奇偶頻次間的最大差值 I6/11 3445. 奇偶頻次間的最大差值 II6/12 3423. 循環數組中相鄰元素的最大差值6/13 2616. 最小化數對的最大…

PyTorch張量操作中dim參數的核心原理與應用技巧:

今天在搭建神經網絡模型中重寫forward函數時,對輸出結果在最后一個維度上應用 Softmax 函數,將輸出轉化為概率分布。但對于dim的概念不是很熟悉,經過查閱后整理了一下內容。 PyTorch張量操作精解:深入理解dim參數的維度規則與實踐…

Day 31

1. 規范的文件命名 核心原則: 清晰明確:文件名應準確描述內容(如data_preprocessing.py) 風格統一: 推薦小寫下劃線(Python慣例,如model_training.py) 或使用駝峰式&#xff08…

學習Oracle------認識VARCHAR2

學習Oracle------認識VARCHAR2 VARCHAR2 是 Oracle 數據庫中專門用于存儲可變長度字符串的數據類型,它是 Oracle 對標準 SQL 數據類型 VARCHAR 的增強和替代。以下是全面解析: 核心概念 名字含義: VAR Variable(可變&#xff09…

記錄jackson解析出錯

Jackson 屬性名大小寫 Bug 記錄 問題描述 在前后端交互過程中,前端傳遞的 JSON 字段名為駝峰風格(如 qTitle),后端 Java 實體類字段名也為駝峰(如 private String qTitle;)。 但在反序列化時,…

泰國數碼電商系統定制|3C產品詳情泰語化+售后管理,適配泰國數碼零售

隨著全球數字化的加速,電商行業正在迅速發展,尤其是以泰國為代表的東南亞市場。泰國不僅是一個擁有龐大消費者群體的市場,而且其日益增長的互聯網使用率和手機普及率使得數碼產品的銷售潛力巨大。在這樣的大背景下,針對泰國市場的…