如何将自己从事件处理程序中删除?

2023-11-26

我想做的基本上是从事件中删除函数,而不知道函数的名称。

我有一个FileSystemWatcher。如果创建/重命名文件,它会检查其名称。如果匹配,则会将其移动到特定位置。但是,如果文件被锁定,它会生成一个附加到计时器的滴答事件的 lambda,等待文件未被锁定。如果不是,它会移动文件,然后将自身从事件处理程序中删除。我见过很多方法可以做到这一点,例如保留实例或创建命名方法。我在这里都做不到。我有什么选择?


没有简单的方法可以实现这一点。

首选方法:

我不明白为什么你不能拯救代表。您不必将实例保存为某个字段。它可以是由匿名事件处理程序捕获的局部变量:

EventHandler<TypeOfEventArgs> handler = null;
handler = (s, e) =>
{
    // Do whatever you need to do here

    // Remove event:
    foo.Event -= handler;
}

foo.Event += handler;

我想不出有什么场景是不能使用它的。

不保存委托的替代方法:

然而,如果你遇到这样的情况,事情就会变得非常棘手。
您需要找到已作为事件处理程序添加的委托。因为你没有保存它,所以很难获得它。没有this获取当前正在执行的方法的委托。

你不能使用GetInvocationList()也可以在事件上,因为访问定义它的类之外的事件仅限于添加和删除处理程序,即+= and -=.

创建新的委托也是不可能的。虽然您可以访问MethodInfo定义匿名方法的对象,您无法访问声明该方法的类的实例。此类由编译器自动生成并调用this匿名方法内部将返回定义普通方法的类的实例。

我发现有效的唯一方法是找到事件使用的字段(如果有)并调用GetInvocationList()在上面。以下代码使用虚拟类演示了这一点:

void Main()
{
    var foo = new Foo();
    foo.Bar += (s, e) => {
        Console.WriteLine("Executed");
        
        var self = new StackFrame().GetMethod();
        var eventField = foo.GetType()
                            .GetField("Bar", BindingFlags.NonPublic | 
                                             BindingFlags.Instance);
        if(eventField == null)
            return;
        var eventValue = eventField.GetValue(foo) as EventHandler;
        if(eventValue == null)
            return;
        var eventHandler = eventValue.GetInvocationList()
                                     .OfType<EventHandler>()
                                     .FirstOrDefault(x => x.Method == self)
                               as EventHandler;
        if(eventHandler != null)
            foo.Bar -= eventHandler;
    };
    
    foo.RaiseBar();
    foo.RaiseBar();
}

public class Foo
{
    public event EventHandler Bar;
    public void RaiseBar()
    { 
        var handler = Bar;
        if(handler != null)
            handler(this, EventArgs.Empty);
    }
}

请注意该字符串"Bar"被传递到GetField需要是确切的名称field事件使用的。这会导致两个问题:

  1. 该字段可以以不同的方式命名,例如当使用显式事件实现时。您需要手动找出字段名称。
  2. 可能根本没有字段。如果事件使用显式事件实现并且仅委托给另一个事件或以其他方式存储委托,则会发生这种情况。

结论:

替代方法依赖于实现细节,因此如果可以避免,请不要使用它。

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

如何将自己从事件处理程序中删除? 的相关文章

  • 语言混合:模型和视图

    考虑开发一个应用程序 其中模型将使用 C 使用 Boost 编写 视图将使用 Objective C 使用 Cocoa Touch 编写 哪里有一些示例展示了如何集成 C 和 Objective C 来开发 iPhone 应用程序 直接从源
  • 使用内部构造函数实例化类

    我有一个类 其构造函数被定义为内部 这意味着我无法实例化它 虽然这可能有道理 但出于调试和研究目的 我仍然愿意做一次 是否可以通过反射来做到这一点 我知道我可以访问私有 内部成员 但是我可以调用内部构造函数吗 或者 由于构造函数没有做任何重
  • 以编程方式 Godaddy 发送的电子邮件不在“已发送邮件”文件夹中 C#.net

    我正在通过以下方式发送电子邮件ASP NET代码使用godaddy邮件服务器 邮件发送成功 但未存储在已发送邮件文件夹中 我正在使用下面的代码 SmtpClient client new SmtpClient client Host smt
  • 在 MVC 类上创建主键字段

    我是 MVC 和 C 新手 我只是偶然发现它并发现它很有趣 我遇到了一个不允许我继续的问题 这是我的代码 using System using System Collections Generic using System Linq usi
  • 此插件导致 Outlook 启动缓慢

    我正在使用 C NET 4 5 开发 Outlook Addin 项目 但部署后 有时 Outlook 会禁用我的插件 并显示此消息 这个插件导致 Outlook 启动缓慢 我不知道我的插件出了什么问题 这只有很少的代码 并且ThisAdd
  • WPF - 按多列排序时使用自定义比较器

    我有一个 ListView GridView 我想按 2 列排序 因此如果第 1 列中有 2 个以上的项目具有相同的值 它将按第 2 列排序 非常简单 但是在对 A Z 进行排序时 空字符串会出现在顶部 我想把它们移到底部 我制作了一个比较
  • 为什么 LinkedList 通常比 List 慢?

    我开始在我的一些 C 算法中使用一些 LinkedList 而不是列表 希望能够加快速度 然而 我注意到他们只是感觉更慢 像任何优秀的开发人员一样 我认为我应该尽职调查并验证我的感受 所以我决定对一些简单的循环进行基准测试 我认为用一些随机
  • 浏览器收集哪些值作为回发数据?

    当页面被发送回服务器时 浏览器收集每个控件的当前值并将其粘贴到一个字符串中 然后 该回发数据通过 HTTP POST 发送回服务器 Q1 除了控件的 Text 属性和 SelectedIndexchanged 因此除了用户输入数据 之外 控
  • C# ConfigurationManager 从 app.config 检索错误的连接字符串

    我有一个简单的 WinForms 应用程序 它最终将成为一个游戏 现在 我正在研究它的数据访问层 但遇到了障碍 我创建了一个单独的项目 名为DataAccess在其中 我创建了一个本地 mdfSQL Server 数据库文件 我还创建了一个
  • 禁用除滚动之外的 DataGridView

    我如何配置 datagridview 以便用户只能在行中移动并使用滚动 而没有其他 如果我禁用网格不允许我使用滚动 将您的 datagridview 设置为只读 这将禁用任何编辑 dataGridView1 ReadOnly true 在你
  • 将语句插入 SQL Server 数据库

    最近几天我试图找到这个错误 但没有成功 我正在尝试在数据库中插入一个新行 一切都很顺利 没有错误 也没有程序崩溃 My INSERT声明如下 INSERT INTO Polozaj Znesek Uporabnik Cas Kupec Po
  • ASP MVC 5 - 403 customError 不起作用

    我正在尝试为我的应用程序创建自定义错误页面 它在大部分情况下都有效 但不适用于403 errors 我的网络配置
  • 从 ef core 的子集合中删除一些项目

    我有一个父表和子表 其中父表与子表具有一对多关系 我想删除一些子项 并且希望父项的子集合反映该更改 如果我使用删除选定的子项RemoveRange 那么子集合不会更新 如果我使用Remove从子集合中删除子集合然后 显然 它不如使用效率高R
  • 在 C# 中生成随机值

    如何使用以下命令生成随机 Int64 和 UInt64 值RandomC 中的类 这应该可以解决问题 这是一个扩展方法 因此您可以像调用普通方法一样调用它Next or NextDouble上的方法Random目的 public stati
  • AspNetCore.SignalR:无法启动未处于初始状态的连接

    我无法让 ASP NET Core SignalR 应用程序正常运行 我有这个服务器端代码 public class PopcornHub Hub private int Users public async Task BroadcastN
  • 从存储过程返回 int 值并在 ASP.NET 代码中检查它以验证登录表单

    当我多次尝试但没有得到有效结果时 使此代码运行的真实顺序是什么 SQL存储过程的代码 set ANSI NULLS ON set QUOTED IDENTIFIER ON GO ALTER PROC dbo login proc usern
  • printf 参数不足

    我的问题是关于缺少参数的 printf 之后的行为 printf s blah blah d int integer was given as argument and not int written 我已经知道 如果格式参数不足 则行为是
  • 统一;随机物体移动[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在制作一款机器人战斗游戏 我希望敌人随机移动 然后有时会向敌人移动 我希望运动包含在其中的代码 else if avoid fal
  • 编译器什么时候内联函数?

    在 C 中 函数仅在显式声明时才内联inline 或在头文件中定义 或者编译器是否允许内联函数 因为他们认为合适 The inline关键字实际上只是告诉链接器 或告诉编译器告诉链接器 同一函数的多个相同定义不是错误 如果您想在标头中定义函
  • 请解释为什么Java和C对此代码给出不同的答案

    public class Test public static void main String args int i 10 i i System out println value of i is i 输出是 10 当我在中执行类似的代码

随机推荐

  • 如何在 web.config 文件中更改我的 asp.net 网站的默认时区

    我正在尝试更改我的 asp net 网站的默认时区 我尝试了以下代码 但它不起作用
  • 如何为 List 实现 Parcelable

    我正在尝试在我的可打包中传递一个列表 public class MetaDados implements Parcelable private List
  • 哈希表与 C++ 中的 STL 映射

    我正在尝试学习 C 地图 只是想知道STL图的实现 我读到它采用了二叉搜索树 STL中有哈希表的实现吗 STL映射到底是如何存储键值对的 典型的 STL 实现基于红黑树 C TR1 提供了 std tr1 unordered map 它使用
  • 如何在 JMeter 中进行 OAuth 2.0 身份验证?

    我正在尝试对一些需要身份验证的 API OAuth 2 0 进行功能测试 并在 JMeter 中进行模拟 我正在尝试验证 Azure 云的 OAuth 服务 有没有人能够成功创建 JMeter HTTP 请求来针对 OAuth 2 0 进行
  • 在文本选择上显示自定义菜单

    您好 我希望能够在用户选择一些与媒体提供的文本非常相似的文本时显示自定义菜单 或上下文菜单 如何实现这样的事情 我知道本机 jquery 上下文菜单插件 但我如何知道用户何时选择文本 浏览器的onselect似乎仅在输入元素上受支持 这是一
  • PHP 的合并函数?

    许多编程语言都有合并函数 返回第一个非 NULL 值 example 遗憾的是 2009 年 PHP 还没有做到这一点 在 PHP 本身获得合并函数之前 在 PHP 中实现一个合并函数的好方法是什么 php 5 3 中有一个新的运算符可以执
  • 如何在 cmd start 中使用引号?

    这是我想做的事 start wait c Program Files NetDrive2 nd2cmd exe c m t ftp blabla If I do start wait c Program Files NetDrive2 nd
  • 如何在 Anaconda Env 中启动 Visual Studio Code

    我在 Windows 10 PC 上的 Visual Studio Code 中运行 Python 程序时遇到问题 当我从终端启动 python 会话并说import cv2我没有收到任何错误 当我通过命令提示符并启动时VSCode从环境中
  • 为什么 UI 元素必须始终从 UI 线程创建/更新?

    为什么 UI 元素必须始终从 UI 线程创建 更新 在 几乎 所有编程语言中 UI 元素只能从 UI 线程安全地访问 修改 我知道这是一个标准的并发访问和同步问题 但真的有必要吗 这种行为是由编程语言还是操作系统强加的 有没有什么编程语言可
  • Django - 仅包含日期部分的分组

    MyModel objects filter created at gte 2011 03 09 created at lte 2011 03 11 values created at status annotate status coun
  • 作为 Cowboy 客户端,您如何使用 Gun?

    我跟着入门说明对于 Cowboy 我让 Cowboy 在端口 8080 上运行并侦听 然后我得到了Hello Erlang 当我进入时的回应http localhost 8080在我的浏览器中 现在 如何使用 Gun 连接到 Cowboy
  • 在类中,“using Base::BaseOfBase;”应该做什么?

    考虑这段代码 include
  • GWT 中的配置参数存储在哪里?

    我可以在客户端哪里存储配置参数 我无法在 Servlet init 参数 web xml 中存储参数 因为我必须使用 PHP 那么我如何在客户端存储初始化应用程序参数 例如 PHP 脚本位置 一些密码等 为此 您有以下选择 将数据存储在客户
  • 对数组进行排序并反映另一个数组中的变化

    我有一个双精度数组 用 Java 编写 arr1我想要排序 最有可能的第一个选项是实用方法Arrays sort double 我的想法是我想要相同的更改 例如 值index i与值互换index j in arr1 反映在另一个整数数组中
  • 如何更改 Flutter 中 EditText 上气泡(光标下)的颜色

    如何更改在 Text 或 TextFormField 或 Flutter 中选择文本时出现的气泡的颜色 Here是同样的问题 但是对于本机代码 根据这个颤振文档 textSelectionHandleColor已弃用 你应该使用select
  • Scala 对现有变量的多重赋值

    我可以做类似的事情 def f Tuple2 String Long val a b f 如果变量已经存在怎么办 我在过滤器上运行相同的数据集 但我不想链接它们 长名称等 这是我尝试过的 但它抱怨期待 而不是最后一行的 var a init
  • 为什么原型函数不影响console.log?

    我制作了原型Function这样它就有一个 getBody 函数 Function prototype getBody function Get content between first and last var m this toStr
  • 列表视图有多个分割按钮吗?

    基于 JQuery Mobile 的示例拆分按钮列表我正在尝试在 Android 中生成一个列表视图组件 右侧有两个额外的按钮 一个紧挨着另一个 问题在于该代码仅生成一个按钮 第二个按钮作为当前项目的链接添加 这是我的代码 ul li a
  • 什么是控制字符的正则表达式?

    我试图匹配 c 形式的控制字符 其中 c 是控制字符的任何有效字符 我有这个正则表达式 但它当前不起作用 z 我认为问题在于插入符 是正则表达式解析引擎的一部分 匹配以下形式的 ASCII 文本字符串 X使用模式 仅此而已 匹配以下形式的
  • 如何将自己从事件处理程序中删除?

    我想做的基本上是从事件中删除函数 而不知道函数的名称 我有一个FileSystemWatcher 如果创建 重命名文件 它会检查其名称 如果匹配 则会将其移动到特定位置 但是 如果文件被锁定 它会生成一个附加到计时器的滴答事件的 lambd