You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#委托单次调用自动订阅取消订阅工具函数实现问询

实现C#委托单次触发后自动取消订阅的工具函数

问题背景

需要实现一个工具函数,为委托订阅目标函数,且目标函数在委托首次触发执行后自动取消订阅。适用场景:

  • 存在大量频繁触发的委托
  • 部分函数仅需在委托首次触发时执行一次
  • 目标函数被多个委托复用,无法在函数内部逐个处理取消订阅逻辑

原尝试代码因局部函数无法访问ref参数导致失效——ref修饰的委托参数无法被局部函数/lambda捕获,无法在wrapper中执行取消订阅操作。

解决方案

通过传递订阅/取消订阅的委托逻辑替代ref参数,让lambda捕获外部的委托变量,从而实现wrapper执行时自动取消自身订阅。

基础版实现(无参数委托)

public void UtilitySingleCall(Action<Action> addSubscription, Action<Action> removeSubscription, Action targetFunc)
{
    // 先声明wrapper变量,确保lambda能引用自身
    Action wrapper = null;
    wrapper = () =>
    {
        // 执行目标函数
        targetFunc();
        // 取消当前wrapper的订阅
        removeSubscription(wrapper);
    };
    // 将wrapper添加到目标委托
    addSubscription(wrapper);
}

使用示例

// 原有的频繁使用的委托
public Action OnRoundStart; 
public Action OnRoundEnd;

// 为两个委托分别订阅MyFunction,指定各自的订阅/取消逻辑
UtilitySingleCall(
    handler => OnRoundStart += handler,
    handler => OnRoundStart -= handler,
    MyFunction
);
UtilitySingleCall(
    handler => OnRoundEnd += handler,
    handler => OnRoundEnd -= handler,
    MyFunction
);

// 首次触发:两次调用MyFunction
OnRoundStart?.Invoke();
OnRoundEnd?.Invoke();

// 后续触发:无任何调用
OnRoundStart?.Invoke();
OnRoundEnd?.Invoke();

public void MyFunction()
{ 
    Console.WriteLine("MyFunction");
}

泛型扩展(支持带参数的委托)

如果需要支持带参数的委托(如Action<T>),可以扩展为泛型版本:

public void UtilitySingleCall<T>(Action<Action<T>> addSubscription, Action<Action<T>> removeSubscription, Action<T> targetFunc)
{
    Action<T> wrapper = null;
    wrapper = (arg) =>
    {
        targetFunc(arg);
        removeSubscription(wrapper);
    };
    addSubscription(wrapper);
}

泛型版使用示例

public Action<string> OnMessageReceived;

// 订阅带参数的目标逻辑
UtilitySingleCall(
    handler => OnMessageReceived += handler,
    handler => OnMessageReceived -= handler,
    message => Console.WriteLine($"Received: {message}")
);

OnMessageReceived?.Invoke("Hello"); // 执行一次,输出"Received: Hello"
OnMessageReceived?.Invoke("World"); // 无输出

方案优势

  • 无需修改原有委托的定义方式
  • 目标函数无需添加标志位或额外逻辑
  • 支持同一个目标函数被多个委托复用,各自独立管理订阅生命周期

内容的提问来源于stack exchange,提问作者TheGrimalkin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:26:16