首页 >后端开发 >C++ >反射如何简化从事件创建异步/等待任务?

反射如何简化从事件创建异步/等待任务?

Barbara Streisand
Barbara Streisand原创
2025-01-05 08:30:09291浏览

How Can Reflection Simplify Async/Await Task Creation from Events?

使用反射从事件完成任务

异步/等待模式允许在事件触发时轻松创建任务。但是,此模式需要每个事件都有一个特定的 FromEvent 方法。为了简化这一点,需要一种更通用的解决方案,其中一个 FromEvent 方法可以处理任何实例上的任何事件。

当直接传递事件或作为字符串传递面临限制时,反射提供了一条潜在的路径。然而,动态创建一个处理程序来在反射中访问 TaskCompletionSource 带来了挑战。

自定义动态方法调用

关键的解决方案涉及创建一个包含所需逻辑的动态方法。此方法的第一个参数是 TaskCompletionSourceHolder 实例。这允许从生成的 IL 中访问 TaskCompletionSource。

帮助器类和扩展方法

帮助器类 TaskCompletionSourceHolder 封装了 TaskCompletionSource 并提供了设置方法它的结果。扩展方法 FromEvent 将源对象和事件名称作为参数。它:

  • 创建了一个新的 TaskCompletionSource 和 TaskCompletionSourceHolder 实例。
  • 使用反射检索事件信息。
  • 使用反射为事件创建委托类型。
  • 验证返回的委托类型void。
  • 生成了一个动态方法,将传递给事件处理程序的参数存储在数组中。
  • 调用了 TaskCompletionSourceHolder.SetResult 方法来设置任务的结果。
  • 已创建来自动态方法的委托并将其添加为事件handler.

支持的事件类型

此解决方案支持任何返回 void 的事件,无论参数列表如何。如果需要,可以进行其他改进以支持任何返回值类型。

示例用法

下面是如何使用自定义 FromEvent 方法的示例:

static async void Run() {
    object[] result = await new MyClass().FromEvent("Fired");
    // Output: 123, abcd
}

public class MyClass {
    // Event delegate type with two parameters
    public delegate void TwoThings(int x, string y);

    // Constructor to trigger event after a delay
    public MyClass() {
        new Thread(() => {
            Thread.Sleep(1000);
            Fired(123, "abcd");
        }).Start();
    }

    // Event using the custom TwoThings delegate
    public event TwoThings Fired;
}

使用我们的通用FromEvent方法,我们可以指定任何事件类型,而不需要显式的任务类型,从而简化事件处理在异步/等待场景中。

以上是反射如何简化从事件创建异步/等待任务?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn