我正在研究Rx.NET,在下面的示例代码中,我尝试执行异步任务,观察日期时间选择器值更改事件。 onNext运行完美但onError和onComplete不运行。我做错了什么?
private void frmReporting_Load(object sender, EventArgs e){
dtPickerValueChanged = Observable.FromEventPattern(
ev => dtPickerFrom.ValueChanged += ev,
ev => dtPickerFrom.ValueChanged -= ev);
dtPickerValueChanged = dtPickerValueChanged.Merge(Observable.FromEventPattern(
ev => dtPickerTo.ValueChanged += ev,
ev => dtPickerTo.ValueChanged -= ev));
dtPickerValueChanged
.Where(x => dtPickerFrom.Value <= dtPickerTo.Value)
.Finally(() => { tsslStatus.Text = "Finally"; })
.ObserveOn(SynchronizationContext.Current)
.Subscribe(
onNext: async x => {
var result = await Test(dtPickerFrom.Value, dtPickerTo.Value);
MessageBox.Show(result);
},
onError: exception => { MessageBox.Show(exception.Message); },
onCompleted: () => { MessageBox.Show("Finished loading data"); });
}
public Task<string> Test(DateTime start, DateTime end){
return Task.Run(
async () =>
{
await Task.Delay(3000);
return start.ToString("dd/MM/yyyy - HH:mm:ss") + " | " + end.ToString("dd/MM/yyyy - HH:mm:ss");
});
}
答案 0 :(得分:0)
当您不使用Rx并简单地附加事件处理程序时,该事件无法告诉您它已完成。处理程序将假设总是会有更多事件,即使它只被调用一次(想想js land中的onLoaded事件)。将事件转换为可观察事件时,您将看到相同的行为; Rx库无法知道事件流是否已经结束。
您始终可以使用Take方法来限制订阅者收到的项目数量。希望这有助于回答为什么观察者永远不会结束
MouseMove.TakeUntil(MouseUp).Subscribe(...);
DocLoad.Take(1).Subscribe(...);
至于OnError永远不会被调用 - 如果你的订阅者抛出一个错误,那么这是你的订阅者的问题,而不是observable本身,让所有其他订阅者知道一个sub变成了流氓是没有意义的。< / p>
OnError通常用于指示在序列中获取值时出错。 e.g。
Observable.Create(sub => {
try {
var res = SomethingThatCanThrow();
sub.OnNext(res);
sub.OnCompleted();
} catch (Exception ex) {
sub.OnError(ex);
}
return Disposable.Empty;
});