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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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产品详情泰语化+售后管理,适配泰国数码零售

随着全球数字化的加速,电商行业正在迅速发展,尤其是以泰国为代表的东南亚市场。泰国不仅是一个拥有庞大消费者群体的市场,而且其日益增长的互联网使用率和手机普及率使得数码产品的销售潜力巨大。在这样的大背景下,针对泰国市场的…