如何解决可观察到的IDisposable对象:如何将先前的值onNext和onComplete处置?
IObservable<Idisposable> disposableValues = source.Select(val => MydisposableObject());
在以下情况下,如何编写用于处理旧值的管道:
- 发出新价值
- 源代码何时完成?
我认为Buffer
可以实现#1,但是如何访问onComplete
callbak上的最后一个值?
disposableValues
.Buffer(2)
.Do(buffer => buffer[0].dispose())
.Finally(_ => { ??})
.Subscribe();
也许我做错了,可以使用CancellationToken
之类的东西...
解决方法
就像我在评论中说的那样,我认为拥有IObservable<IDisposable>
有点奇怪。在这样的可观察管道中很难推断一次性用品的使用寿命。
更有可能的是,您有一个可观察物体,需要使用您要想要做的事的一次性对象,并希望确保以后将其丢弃。
让我们假设您有这种一次性用品:
public class MyDisposableObject : IDisposable
{
public void DoSomething()
{
Console.WriteLine("DoSomething!");
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
Console.WriteLine("Dispose!");
}
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
它有事要做,让我们知道它何时处置。
现在查询。
var source = new Subject<Unit>();
IObservable<Unit> observable =
source
.SelectMany(u =>
Observable.Using(
() => new MyDisposableObject(),mdo => Observable.Start(() => mdo.DoSomething())));
observable.Subscribe();
它使用Observable.Using
运算符创建一次性对象,然后能够启动使用一次性对象的可观察对象。一旦完成,或者source
可观察项完成,一切都会被丢弃。
尝试以下测试代码:
source.OnNext(Unit.Default);
source.OnNext(Unit.Default);
source.OnNext(Unit.Default);
source.OnCompleted();
那给了我
DoSomething!
Dispose!
DoSomething!
DoSomething!
Dispose!
Dispose!
一切都摆放得很好,并且创建了一个清晰可见的观察结果,没有任何副作用。
,使用name
是获取“上一个”对象的正确方法,但是您应使用const handleItemClick = (e,{ name }) => console.log(name);
handleItemClick(
new MouseEvent("click"),// First argument,not used by the handler
{name: "Joe"} // Second argument,Used by the handler
);
获取“滑动窗口”。然后,您以默认值(例如Buffer()
)开始订阅,并以默认值(也为Buffer(2,1)
)结束订阅。目标是得到这样的序列:
null
您将有四个事件,对于其中三个事件,您可以致电null
。
对于第一个[null,obj1]
[obj1,obj2]
[obj2,obj3]
[obj3,null]
,您可以使用在实际数据之前的Dispose()
。对于最后一个null
,您可以使用StartWith(null)
和null
和Concat()
添加一个observable with only one value。当原始的可观察对象完成时,您将获得一个“伪造”事件,您可以在其中处置上次使用的对象。检查以下示例:
Observable.Never()
这将生成以下调试输出:
StartWith()
,
您可能想要的是与Do
运算符类似的东西,但对于前一个元素。以下是自定义DoOnPrevious
运算符的实现:
/// <summary>Invokes an action for the previous element in the observable
/// sequence. The action for the last element is invoked when the observable
/// sequence completes.</summary>
private static IObservable<T> DoOnPrevious<T>(this IObservable<T> source,Action<T> onPrevious)
{
return source
.Select(x => (Item: x,HasValue: true))
.Append((default,false))
.Scan((previous,current) =>
{
if (previous.HasValue) onPrevious(previous.Item);
return current;
})
.Where(entry => entry.HasValue)
.Select(entry => entry.Item);
}
用法示例:
disposableValues
.DoOnPrevious(x => x.Dispose())
.Subscribe();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。