EventHandler:这段代码发生了什么?

2024-04-16

此代码为名为的事件添加注册新的 EventHandler(s)NewMail(eventargs 类被命名为NewMailEventArgs.

// A PUBLIC add_xxx method (xxx is the event name)
// Allows methods to register interest in the event.
public void add_NewMail(EventHandler<NewMailEventArgs> value) {
  // The loop and the call to CompareExchange is all just a fancy way
  // of adding a delegate to the event in a thread-safe way.
  EventHandler<NewMailEventArgs> prevHandler;
  EventHandler<NewMailEventArgs> newMail = this.NewMail;
  do {
     prevHandler = newMail;
     EventHandler<NewMailEventArgs> newHandler = (EventHandler<NewMailEventArgs>)Delegate.Combine(prevHandler, value);
     newMail = Interlocked.CompareExchange<EventHandler<NewMailEventArgs>>(ref this.NewMail, newHandler, prevHandler);
    }
  while(newMail != prevHandler);
}

(来源:CLR via C#,第 11 章事件) 我不明白的是 do 部分,首先我们将 newMail 分配给 prevHandler,然后 newMail 更改(在 CompareExchange 中)为 newHandler?然后我们检查 newMail != prevHandler 是否?
我真的有点困惑。任何人都可以帮助我理解这里到底发生了什么,特别是在 do 循环中?


正如评论所说,它是为了提供一种安全的方式来处理多线程环境中的事件。这实际上非常棘手,但它的工作原理如下:

  • 什么是Interlocked.CompareExchange is : if prevHandler == this.NewMail, then this.NewMail = newHandler

  • 整个操作(比较+影响)是atomic, i.e. 一次性完成(不能在操作过程中被另一个线程停止)。

  • If NewMail不等于prevHandler,那么这意味着另一个线程已经运行了相同的代码并且已经修改了事件处理程序。所以我们不会在这里做任何事情,我们会循环并重试,希望下次没有其他线程已经注册了一个事件处理程序(下次我们将re-read事件处理程序;现在将考虑另一个线程完成的操作)。

另请参阅这个有用的thread https://stackoverflow.com/questions/786383/c-sharp-events-and-thread-safety.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EventHandler:这段代码发生了什么? 的相关文章

  • 为什么存在 async 关键字

    浏览 msdn 9 频道视频时 我发现以下未答复的评论 希望有人能解释一下 我不明白 async 关键字的意义 为什么不直接允许 任何时候方法返回任务时都会使用await关键字 就像迭代器一样 可以在任何返回 IEnumerable 的方法
  • Subversion 和 Visual Studio 项目的最佳实践

    我最近开始在 Visual Studio 中处理各种 C 项目 作为大型系统计划的一部分 该系统将用于替换我们当前的系统 该系统是由用 C 和 Perl 编写的各种程序和脚本拼凑而成的 我现在正在进行的项目已经达到了颠覆的临界点 我想知道什
  • 将字节数组转换为托管结构

    更新 这个问题的答案帮助我编写了开源项目GitHub 上的 AlicanC 现代战争 2 工具 https github com AlicanC AlicanC s Modern Warfare 2 Tool 你可以看到我是如何阅读这些数据
  • ASP.NET Core 与现有的 IoC 容器和环境?

    我想运行ASP NET 核心网络堆栈以及MVC在已托管现有应用程序的 Windows 服务环境中 以便为其提供前端 该应用程序使用 Autofac 来处理 DI 问题 这很好 因为它已经有一个扩展Microsoft Extensions D
  • 选择列表逻辑应位于 ASP.NET MVC、视图、模型或控制器中的什么位置?

    我觉得我的问题与这个问题很接近 但我想对这样的代码应该放在哪里进行更一般的讨论 Asp Net MVC SelectList 重构问题 https stackoverflow com questions 2149855 asp net mv
  • mprotect 之后 malloc 导致分段错误

    在使用 mprotect 保护内存区域后第一次调用 malloc 时 我遇到分段错误 这是执行内存分配和保护的代码片段 define PAGESIZE 4096 void paalloc int size Allocates and ali
  • 如何使用MySqlCommand和prepare语句进行多行插入?(#C)

    Mysql 给出了如何使用准备语句和 NET 插入行的示例 http dev mysql com doc refman 5 5 en connector net programming prepared html http dev mysq
  • 带 If 的嵌套 For 循环的时间复杂度

    void f int n for int i 1 i lt n i if i int sqrt n 0 for int k 0 k lt pow i 3 k do something 我的思考过程 执行if语句的次数 sum i 1 to
  • 无法解析远程名称 - webclient

    我面临这个错误 The remote name could not be resolved russgates85 001 site1 smarterasp net 当我请求使用 Web 客户端读取 html 内容时 出现错误 下面是我的代
  • 如何在 C++ 中将 CString 转换为 double?

    我如何转换CString to a double在 C 中 Unicode 支持也很好 Thanks A CString可以转换为LPCTSTR 这基本上是一个const char const wchar t 在 Unicode 版本中 知
  • C# 委托责任链

    为了我的理解目的 我实现了责任链模式 Abstract Base Type public abstract class CustomerServiceDesk protected CustomerServiceDesk nextHandle
  • libxml2 xmlChar * 到 std::wstring

    libxml2似乎将所有字符串存储在 UTF 8 中 如xmlChar xmlChar This is a basic byte in an UTF 8 encoded string It s unsigned allowing to pi
  • C++11 动态线程池

    最近 我一直在尝试寻找一个用于线程并发任务的库 理想情况下 是一个在线程上调用函数的简单接口 任何时候都有 n 个线程 有些线程比其他线程完成得更快 并且到达的时间不同 首先我尝试了 Rx 它在 C 中非常棒 我还研究了 Blocks 和
  • C# 中的常量和只读? [复制]

    这个问题在这里已经有答案了 可能的重复 const 和 readonly 之间有什么区别 https stackoverflow com questions 55984 what is the difference between cons
  • 如何随着分辨率的变化自动调整大小和调整表单控件

    我注意到某些应用程序会更改控件的位置以尽可能适应当前的分辨率 例如 如果窗口最大化 则控件的设置方式应使整个 GUI 看起来平衡 是否可以使用 C 在 Visual studio 2010 中制作或实现此功能 Use Dock http m
  • DataTable:通过 LINQ 或 LAMBDA 进行动态 Group By 表达式

    我有一个数据表 我想在其中对未指定数量的字段进行分组 发生这种情况的原因是用户可以选择他想要分组的字段 所以 实际上 我将选择推入列表中 在这个选择上 我必须对我的数据表进行分组 想象一下这段代码 VB 或 C 都一样 public voi
  • 初始化 LPCTSTR /LPCWSTR [重复]

    这个问题在这里已经有答案了 我很难理解并使其正常工作 基本上归结为我无法成功初始化这种类型的变量 它需要有说的内容7 2E25DC9D 0 USB003 有人可以解释 展示这种类型的正确初始化和类似的值吗 我已查看此站点上的所有帮助 将项目
  • C语言声明数组没有初始大小

    编写一个程序来操纵温度详细信息 如下所示 输入要计算的天数 主功能 输入摄氏度温度 输入功能 将温度从摄氏度转换为华氏度 独立功能 查找华氏度的平均温度 我怎样才能在没有数组初始大小的情况下制作这个程序 include
  • C++、三元运算符、std::cout

    如何使用 C 用三元运算符编写以下条件 int condition1 condition2 condition3 int double result int or double std cout lt lt condition1 resul
  • 以 UTF8 而不是 UTF16 输出 DataTable XML

    我有一个 DataTable 我正在使用 WriteXML 创建一个 XML 文件 尽管我在以 UTF 16 编码导出它时遇到问题 并且似乎没有明显的方法来更改它 我了解 NET 在字符串内部使用 UTF 16 这是正确的吗 然后 我通过

随机推荐

  • C# 中的委托数组

    我正在尝试从委托数组调用委托函数 我已经能够创建委托数组 但是如何调用委托呢 public delegate void pd public static class MyClass static void p1 static void p2
  • Spring 提供静态内容,同时具有通配符控制器路由

    我的应用程序是在前端使用骨干和后端使用 spring 框架构建的 这是一个单一的 html 应用程序 路由由骨干网处理 因此我有一个具有以下结构的后端路由 RequestMapping value method RequestMethod
  • 如何调用maven默认生命周期

    如果我打电话 mvn clean install maven知道clean是一个生命周期 install是默认生命周期的一个阶段 如果我打电话 mvn deploy maven 将按顺序执行默认生命周期的所有阶段 有没有办法通过给出生命周期
  • Mac OS X:尝试链接(ld)到框架

    我正在阅读 Mark 和 Aaron 所著的 高级 Mac OS X 编程 我无法让一个终端语句正常工作 cc g o useadd F Adder build framework 加法器 useadd m 它位于第 45 页 第 3 章
  • Angular2 - 多个依赖的顺序 http api 调用

    我正在构建一个 Angular2 应用程序 其中一个组件需要进行多个 API 调用 这些调用依赖于之前的调用 我目前有一项服务可以调用 API 来获取电视节目列表 对于每个节目 我需要多次调用不同的 API 来逐步检查该结构 以确定该节目是
  • 在rocker/shiny docker中部署shiny应用程序

    嗯 我是新来的Docker我需要在 Docker 容器中实现一个闪亮的应用程序 我有来自的图像https hub docker com r rocker shiny https hub docker com r rocker shiny 包
  • 操作链接到同一页面

    我需要创建一个 html 操作链接 相当于 a href Test Link a 或当前页面的操作链接 有人有例子吗 你可以尝试用这个 a href Url Action null Test Link a 帮手Url Action第一个参数
  • SQL 查询 C# 的 In 子句中的多个 ID [已关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我基本上想在 sql 查询的 In 子句中使用多个 iD 现在我有两个选择 一个是从文本框中获取逗号分隔的 ID 或者我可以放置一个列表视图
  • MySQL临时表是共享资源吗?

    我有一个使用临时表的 MySQL 存储过程 假设我的表名称是 temp 我用它来存储一些中间数据 它将在程序开始时创建 并在程序结束时删除 CREATE PROCEDURE p BEGIN CREATE TEMPORARY TABLE te
  • 堆中的 siftUp 和 siftDown 操作用于堆化数组

    假设 MAX HEAPIFY 操作 其中父元素值大于其子元素值 siftDown 将太小的节点与其最大的子节点交换 从而将其向下移动 直到它至少与两个节点一样大 在它下面 siftUp 将太大的节点与其父节点交换 从而移动 直到它不大于它上
  • 如何在 android O 的系统设置中对通知渠道进行排序

    我有预设的通知渠道顺序 可以更改 如何更改通知渠道的顺序 我尝试按channel id和channel name排序 但不起作用 我的解决方案有错误 我尝试在频道 ID 的开头添加频道数以进行排序 所以我有这个 56 server chan
  • 在iOS中,使用故事板,如何在容器视图内设置视图控制器?

    我在主故事板中创建并绘制了一个名为 AutocompleteVC 的自定义 UIViewController AutocompleteVC 将用于几个不同的地方 故事板和不同的维度 例如 在我的 Transit 故事板中 如下所示 有一个名
  • 浮点数的哈希函数

    我目前正在 C 中实现一个哈希表 并且正在尝试为浮点数创建一个哈希函数 我本来打算通过填充小数来将浮点数视为整数 但后来我意识到我可能会用大数字来溢出 有没有好的方法来散列浮点数 您不必直接给我该功能 但我想看到 理解不同的概念 Notes
  • 在 SQL*Plus 中将字符集设置为 UTF-8

    我有一个 SQL 脚本 其中包含以下语句 insert into employee fname lname values J rg M ller 我的数据库字符集设置为 AL32UTF8 但是当我在 SQL 中执行脚本时另外 德语字母 和
  • ggplot2,在 x 对数刻度上引入中断

    我有一个这样的情节 p lt ggplot geom line data myData aes x myData x y myData y scale x log10 scale y log10 我的x值是seq 9880000 12220
  • 如何使用 jQuery 获取 attr?

    div class item p img src images photos sample1 jpg border 0 p p Dining Area p div div class item p img src images photos
  • boost.python公开返回向量的函数

    我正在用 C 编写 Python 扩展模块 并且使用 boost python 我想公开一个返回a的函数vector
  • 如何根据值检查复选框?

    我返回一个 JSON 数据结构 我将其拆分并填充数组 如下所示 var arrayValues data contents split arrayValues 1 3 4 如何根据数组值检查相应的复选框 我的 HTML 看起来像这样 div
  • UILabel + touchDown

    UILabel可以实现touchdown吗 UILabel是一个子类UIView 它本身是一个子类UIResponder 因此 制作一个响应触摸的标签绝对是可能的 只需创建一个新的子类UILabel并实施以下方法 touchesBegan
  • EventHandler:这段代码发生了什么?

    此代码为名为的事件添加注册新的 EventHandler s NewMail eventargs 类被命名为NewMailEventArgs A PUBLIC add xxx method xxx is the event name All