C# Rx.NET不会触发onError或onComplete

C# Rx.NET不会触发onError或onComplete,c#,events,asynchronous,rx.net,C#,Events,Asynchronous,Rx.net,我正在研究Rx.NET,在下面的示例代码中,我试图执行一个异步任务,观察日期时间选择器值更改事件。 onNext运行得很好,但onError和onComplete则不行。我做错了什么 private void frmReporting_Load(object sender, EventArgs e){ dtPickerValueChanged = Observable.FromEventPattern( ev => dtPickerFrom.ValueChanged

我正在研究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");
        });
}
private void frmReporting\u加载(对象发送方,事件参数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{tsslStatus.Text=“Finally”;})
.ObserveOn(SynchronizationContext.Current)
.订阅(
onNext:async x=>{
var结果=等待测试(dtPickerFrom.Value,dtPickerTo.Value);
MessageBox.Show(结果);
}, 
onError:exception=>{MessageBox.Show(exception.Message);},
未完成:()=>{MessageBox.Show(“已完成加载数据”);});
}
公共任务测试(日期时间开始,日期时间结束){
返回任务。运行(
异步()=>
{
等待任务。延迟(3000);
返回start.ToString(“dd/MM/yyyy-HH:MM:ss”)+“|”+end.ToString(“dd/MM/yyyy-HH:MM:ss”);
});
}

当您不使用Rx而只是附加一个事件处理程序时,该事件无法告诉您它已完成。处理程序将假定总是会有更多的事件,即使只调用一次(想想js land中的onLoaded事件)。将事件转换为可观察事件时,您将看到相同的行为;Rx库无法知道事件流是否已结束

您始终可以使用Take方法来限制订户接收的项目数量。希望这有助于回答为什么观测永远不会结束

MouseMove.TakeUntil(MouseUp).Subscribe(...);
DocLoad.Take(1).Subscribe(...);
至于从未被调用的OnError-如果您的订阅者抛出错误,那么这是订阅者的问题,而不是可观察对象本身,让所有其他订阅者知道一个sub出错是没有意义的

OneError通常用于指示在获取序列中的值时出错。e、 g

Observable.Create(sub => {
    try {
        var res = SomethingThatCanThrow();
        sub.OnNext(res);
        sub.OnCompleted();
    } catch (Exception ex) {
        sub.OnError(ex);
    }

    return Disposable.Empty;
});

为什么您希望
onError
onCompleted
开火?没有什么是结束事件流或抛出错误。如果我在onNext中添加抛出新异常(“无论什么”),它将无法在onError上跟踪它。关于未完成,我如何结束可观察的,而不是一次性的?我看过很多教程和代码示例,但我从来没有找到关于何时调用每个操作的好解释。