从非标准事件创建可观察事件(无EventArgs/EventHandler) [英] Create Observable from non-standard event (no EventArgs / EventHandler)

查看:34
本文介绍了从非标准事件创建可观察事件(无EventArgs/EventHandler)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要为定义如下的事件创建可观测对象:

public event Func<Exception, Task> Closed;

我当前的代码是这样的:

Observable.FromEvent<Func<Exception, Task>, Unit>(h => hub.Closed += h, h=> hub.Closed -= h); 

编译正常,但引发此运行时异常:

System.ArgumentException:‘无法绑定到目标方法,因为 其签名或安全透明度与的签名或安全透明度不兼容 委托类型。"

我觉得我做错了。我不习惯从不遵循EventArgs模式😔的事件创建可观测对象

编辑:仅为澄清起见,以下是经典事件处理的完整代码:

class Program
{
    static async Task Main(string[] args)
    {
        var hub = new HubConnectionBuilder().WithUrl("http://localhost:49791/hubs/status")
            .Build();

        hub.On<Status>("SendAction", status => Console.WriteLine($"Altitude: {status.Altitude:F} m"));
        await hub.StartAsync();

        hub.Closed += HubOnClosed;

        while (true)
        {
        }
    }

    private static Task HubOnClosed(Exception arg)
    {
        Console.WriteLine("The connection to the hub has been closed");
        return Task.CompletedTask;
    }
}

推荐答案

您需要转换重载。我每次查这个的时候都会关机:

IObservable<TEventArgs> Observable.FromEvent<TDelegate, TEventArgs>(
    Func<Action<TEventArgs>, TDelegate> conversion, 
    Action<TDelegate> addHandler, 
    Action<TDelegate> removeHandler>
)

因此,在我们的示例中,TEventArgsExceptionTDelegateFunc<Exception, Task>,因此您需要将Action<Exception>转换为Func<Exception, Task>>,换言之:Func<Action<Exception>, Func<Exception, Task>>。我假设转换如下:a => e => {a(e); return Task.CompletedTask; }

System.Reactive需要此转换函数,因为它需要使用适当的委托订阅事件,并以某种方式挂接您的代码/接收管道代码。在本例中,a(e)基本上是RX管道,然后传递异常以便稍后在反应式管道中进行处理。

完整代码:

class Program
{
    static async Task Main(string[] args)
    {

        Program.Closed += Program.HubOnClosed;
        Observable.FromEvent<Func<Exception, Task>, Exception>(
            a => e => {a(e); return Task.CompletedTask; }, 
            h => Program.Closed += h, 
            h => Program.Closed -= h
        )
            .Subscribe(e =>
            {
                Console.WriteLine("Rx: The connection to the hub has been closed");
            });

        Program.Closed.Invoke(null);
        Program.Closed.Invoke(null);
    }

    private static Task HubOnClosed(Exception arg)
    {
        Console.WriteLine("The connection to the hub has been closed");
        return Task.CompletedTask;
    }

    public static event Func<Exception, Task> Closed;
}

这篇关于从非标准事件创建可观察事件(无EventArgs/EventHandler)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆