我无法弄清楚为什么以下代码无法运行 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();
}
}
事件永远不会完成,因为这不是事件中存在的概念。 IE。事件无法表示它将不再产生更新。处理对可观察量的订阅并不意味着该可观察量已完成,而只是意味着您不再观察它。
顺便说一句,您应该只订阅可观察一次,而不是在循环内。处理订阅也是如此。