.NET 的反应式扩展(Rx):在所有事件完成后执行操作

15

作为概念验证,我想在一个文本框中写入“已完成”,复选框被勾选并且文本框中按下了一个键之后(顺序不限)。我期望这段代码可以处理此操作,但它会在任何一个事件发生时就立即写入“已完成”。谢谢您的帮助。

var seq = Observable.FromEvent<EventArgs>(this.checkBox, "CheckedChanged")
   .Merge(Observable.FromEvent<KeyPressEventArgs>(this.textBox, "KeyPress"));

seq.Subscribe((unused) => this.resultTextBox.Text = "Done");
2个回答

25
您可以使用Observable.When,如下所示(我为此示例添加了一个额外的复选框):
var checkChanged  = Observable.FromEvent<EventArgs>(this.checkBox, "CheckedChanged");
var check1Changed = Observable.FromEvent<EventArgs>(this.checkBox1, "CheckedChanged");
var keyPress      = Observable.FromEvent<KeyPressEventArgs>(this.textBox, "KeyPress");

var plan1 = checkChanged
            .And(check1Changed).And(keyPress)
            .Then((cc, cc1, kp) => "Done.");

var when = Observable.When(plan1);

when.Subscribe((result) => this.resultTextBox.Text = result);

此外,如果您可以将其他计划组合在一起,例如当一个事件集触发时可以“完成”,或者当另一个事件集也触发时也可以“完成”:

var checkChanged  = Observable.FromEvent<EventArgs>(this.checkBox, "CheckedChanged");
var check1Changed = Observable.FromEvent<EventArgs>(this.checkBox1, "CheckedChanged");
var keyPress      = Observable.FromEvent<KeyPressEventArgs>(this.textBox, "KeyPress");
var keyPress1     = Observable.FromEvent<KeyPressEventArgs>(this.textBox1, "KeyPress");

var plan1 = checkChanged.And(check1Changed).And(keyPress).Then((cc, cc1, kp) => "Done.");
var plan2 = keyPress.And(keyPress1).Then((kp, kp1) => "Alternate done.");

var join = Observable.When(plan1, plan2);

谢谢 - 我也玩过这种方法。如果这些事件是异步网络调用,你会更喜欢这种风格而不是Zip方法吗? - Marcel Lamothe
我喜欢那个。在这些事件中处理错误条件是一个微不足道的事情吗? - Marcel Lamothe
顺便说一下,我还没有尝试使用Zip来做这件事。也许我稍后会尝试一下以进行比较。 - Richard Anthony Freeman-Hein
1
通过使用带有 OnError Action 的 Subscribe 重载来处理错误。例如:join.Subscribe((result) => this.resultTextBox.Text = result, ex => Console.WriteLine("Error: {0}", ex.Message)); - Richard Anthony Freeman-Hein

1
如果您需要这两个事件同时发生 - 考虑使用 Zip。Merge 将会在合并的源中 任意一个 触发事件时触发它。

如果有10个不同的事件,而不是两个呢? - Marcel Lamothe
Zip返回Observable,当两个源同时触发时(如会合),它将触发事件。您可以将此结果Observable与另一个Observable连接以获得连接到3个源等的Observable... - desco
这种方法可行吗?使用Observable.Join和Ands呢? - Marcel Lamothe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接