正如我原来的问题所述(参见Correlate interdependent Event Streams with RX.Net)我有一个RX.net事件流,只要没有触发某个其他事件,它就只能调用观察者的OnNext方法(基本上是'Handle Change- *系统连接时的事件,断开连接时暂停,并在系统重新连接后重新开始处理Change- *事件。
然而,虽然这对新活动顺利进行,但我如何取消/取消取消正在进行的 .OnNext()电话?
答案 0 :(得分:1)
由于您的观察者已经被编写为接受CancellationToken
,我们可以修改您的Rx流以提供一个事件数据。我们将使用我们将在取消订阅流时处理的Rx CancellationDisposable
。
// Converts into a stream that supplies a `CancellationToken` that will be cancelled when the stream is unsubscribed
public static IObservable<Tuple<CancellationToken, T>> CancelOnUnsubscribe<T>(this IObservable<T> source)
{
return Observable.Using(
() => new CancellationDisposable(),
cts => source.Select(item => Tuple.Create(cts.Token, item)));
}
将其与其他问题的解决方案结合起来:
DataSourceLoaded
.SelectMany(_ => DataSourceFieldChanged
.Throttle(x)
.CancelOnUnsubscribe()
.TakeUntil(DataSourceLoaded))
.Subscribe(c => handler(c.Item1, c.Item2));
当触发TakeUntil
子句时,它将取消订阅CancelOnUnsubscribe
observable,后者将依次处理CancellationDisposable
并导致令牌被取消。当发生这种情况时,您的观察者可以观察此标记并停止其工作。
答案 1 :(得分:0)
SelectMany
存在异步重载,但是如果存在类似Do
的重载,那么它在语义上更合适。
var subscription =
(from _ in DataSourceLoaded
from __ in DataSourceFieldChanged
.Throttle(x)
.SelectMany(DataSourceFieldChangedAsync)
.TakeUntil(DataSourceUnloaded)
select Unit.Default);
.Subscribe(); // Subscribing for side effects only.
...
async Task<Unit> DataSourceFieldChangedAsync(Field value, CancellationToken cancel);
这很好,因为它也取消了对订阅的取消。
调用
subscription.Dispose()
或
DataSourceUnloaded.OnNext(x);
会导致CancellationToken
被取消。