我在学习RX,并想使用Console.ReadLine作为可观察序列的源。Console.ReadLine()传递给C#事件
我知道我可以使用“yield return”创建“IEnumerable”,但是对于我的具体用例,我决定创建一个C#事件,以便可能很多观察者可以共享相同的键盘输入。
这里是我的代码:
class Program
{
private delegate void OnNewInputLineHandler(string line);
private static event OnNewInputLineHandler OnNewInputLineEvent = _ => {};
static void Main(string[] args)
{
Task.Run((Action) GetInput);
var input = ConsoleInput();
input.Subscribe(s=>Console.WriteLine("1: " + s));
Thread.Sleep(30000);
}
private static void GetInput()
{
while (true)
OnNewInputLineEvent(Console.ReadLine());
}
private static IObservable<string> ConsoleInput()
{
return Observable.Create<string>(
(IObserver<string> observer) =>
{
OnNewInputLineHandler h = observer.OnNext;
OnNewInputLineEvent += h;
return Disposable.Create(() => { OnNewInputLineEvent -= h; });
});
}
}
我的问题 - 当我运行GetInput方法,因为它上面显示,第一个输入线不被发送到序列(但它发送到事件处理程序)。
但是,如果我用下面的版本来替换它,一切都按预期工作:
private static void GetInput()
{
while (true)
{
var s = Console.ReadLine();
OnNewInputLineEvent(s);
}
}
可能有人能够解释为什么这件事会发生一些轻?
感谢您的提示! 但它不回答我的问题 - 为什么一个版本的工作原理: var s = Console.ReadLine(); OnNewInputLineEvent(s); OnNewInputLineEvent(s); 而另一个则丢失第一个通知: OnNewInputLineEvent(Console.ReadLine()); – Natan
@Natan - 我要猜测竞赛状况,但很难证明。生成的IL非常相似 - 只是首先将字符串存储在变量中。它可能只是采取一些命令更长的时间。对我来说似乎有点狡猾。 – Enigmativity
这也是我的第一个想法。我还浏览了IL代码,无法分辨出为什么这会起作用。但是,如果这是一个竞争条件,它不会那么一致!这在Debug和Release版本中是一样的,如果我直接运行或者在调试器中运行。我想我需要构建RX并尝试调试,但我不确定这是否值得付出努力。 – Natan