.NET Rx C# Observable.FromEventPattern 不运行 OnCompleted

问题描述 投票:0回答:1

我无法弄清楚为什么以下代码无法运行 OnCompleted,任何人都可以帮助我,谢谢。

基本上我所做的就是每次按下一个键时,我都会触发一个事件并将该事件转换为可观察的事件,以便我可以订阅观察者。观察者只需打印出文本即可。一旦 observable 被消耗掉(这意味着在 do while 循环中调用 Dispose),处理订阅也是个好主意吗?

我通过 Nuget 使用 .Net Rx - System.Reactive (6.0.0)

这是终端上显示结果的屏幕截图

//Create observable from Observable.FromEventPattern
public class MainApp
{
    public event EventHandler<DeviceEventArgs>? DeviceEvent;
    private ConsoleKeyInfo ch;

    public void Start()
    {
        string[] deviceNames = ["Loop", "Sick", "RFID Reader", "Barrier"];
        string[] deviceStatus = ["On", "Off"];
        var rand = new Random();

        IDisposable devEventSubscription;
        var deviceEventObservables = Observable.FromEventPattern<EventHandler<DeviceEventArgs>, DeviceEventArgs>(
                h => DeviceEvent += h,
                h => DeviceEvent -= h)
            .Select(ep => ep.EventArgs);
        do
        {
            Console.WriteLine("Press space bar or enter to exit the program");
            ch = Console.ReadKey();
            Console.WriteLine();

            // Assume ch is data stream from the device that need to convert to Observables
            Console.WriteLine($"Char {ch.KeyChar} was entered");

            devEventSubscription = deviceEventObservables.Subscribe((eventArgs) =>
            {
                Console.WriteLine($"Received an observable. Time: {eventArgs.Epoch}. Type: {eventArgs.DeviceName}. Status: {eventArgs.Status}");
            },
            () => Console.WriteLine("Completed"));

            if (DeviceEvent != null)
            {
                DeviceEvent(null, new DeviceEventArgs()
                {
                    Epoch = DateTimeOffset.Now.ToUnixTimeSeconds(),
                    Status = deviceStatus[rand.Next(deviceStatus.Length)],
                    DeviceName = deviceNames[rand.Next(deviceNames.Length)]
                });
            }
            // Question: why i dont' see the Completed message from the OnCompleted and
            // should i move this line out of the do while loop?
            devEventSubscription?.Dispose();

        } while (!char.IsWhiteSpace(ch.KeyChar));
        
        Console.ReadKey();
    }
}


class Sample
{
    private static void Main()
    {
        var m = new MainApp();
        m.Start();
    }
}
c# observable reactive-programming system.reactive observer-pattern
1个回答
0
投票

事件永远不会完成,因为这不是事件中存在的概念。 IE。事件无法表示它将不再产生更新。处理对可观察量的订阅并不意味着该可观察量已完成,而只是意味着您不再观察它。

顺便说一句,您应该只订阅可观察一次,而不是在循环内。处理订阅也是如此。

© www.soinside.com 2019 - 2024. All rights reserved.