如果我有权访问一个我知道只会返回一个项目的IObservable,这会有效吗?它是最好的使用模式吗?
IDisposable disposable = null;
disposable = myObservable.Subscribe(x =>
{
DoThingWithItem(x);
if (disposable != null)
{
disposable.Dispose();
}
});
答案 0 :(得分:50)
Subscribe
扩展方法返回的一次性返回仅用于允许您手动取消订阅可观察之前可观察的自然结束。
如果observable完成 - 使用OnCompleted
或OnError
- 那么订阅已经为您处理。
试试这段代码:
var xs = Observable.Create<int>(o =>
{
var d = Observable.Return(1).Subscribe(o);
return Disposable.Create(() =>
{
Console.WriteLine("Disposed!");
d.Dispose();
});
});
var subscription = xs.Subscribe(x => Console.WriteLine(x));
如果你运行上述内容,你会看到“Disposed!”在observable完成时写入控制台,而不需要在订阅上调用.Dispose()
。
需要注意的一件重要事情:垃圾收集器永远不会在可观察订阅上调用.Dispose()
,因此如果他们之前没有(或可能没有)自然结束,那么必须处理您的订阅您的订阅超出范围。
拿这个,例如:
var wc = new WebClient();
var ds = Observable
.FromEventPattern<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs>(
h => wc.DownloadStringCompleted += h,
h => wc.DownloadStringCompleted -= h);
var subscription =
ds.Subscribe(d =>
Console.WriteLine(d.EventArgs.Result));
ds
observable仅在具有订阅时附加到事件处理程序,并且仅在observable完成或处理订阅时才分离。因为它是一个事件处理程序,所以observable永远不会完成,因为它正在等待更多的事件,因此处理是从事件中分离的唯一方法(对于上面的例子)。
当你有一个FromEventPattern
observable,你知道它只会返回一个值,那么在订阅之前添加.Take(1)
扩展方法是明智的,允许事件处理程序自动分离然后你不要需要手动处理订阅。
像这样:
var ds = Observable
.FromEventPattern<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs>(
h => wc.DownloadStringCompleted += h,
h => wc.DownloadStringCompleted -= h)
.Take(1);
我希望这会有所帮助。
答案 1 :(得分:12)
免责声明:我还在学习Rx。所以我不是真正的专家,但我相信Subscribe
返回的一次性用品只会取消订阅。此外,如果源完成,就像您的情况一样,取消订阅会自动完成。所以我认为Dispose
存在冗余,可以安全删除。
有关详细信息,请参阅此question的答案。
答案 2 :(得分:4)
Take
功能将完全符合您的要求。在这种情况下,Take(1)
。
答案 3 :(得分:0)
与某些评论相反,从OnNext
内部处理订阅并不罕见。
虽然OnCompleted
和OnError
的处理是通过Subscribe
扩展方法创建的包装订阅为您完成的,但您可能希望根据您正在观察的值取消订阅(在你的情况下:第一个)。您并不总是有一个已知只能产生一个值的可观察量。
问题是,只有在订阅后才能获得IDisposable
。即使在OnNext
退回IDisposable
取消订阅之前,观察者也可能会再次通过IScheduler
给您回电(具体取决于其使用的System.Reactive.Disposables.SingleAssignmentDisposable
)。
IDisposable
在这种情况下派上用场。如果SingleAssignmentDisposable
已经被处理掉,那么它会包含您可能迟到的IsDisposed
,并会立即处理它。此外,它还带有false
的属性,该属性最初为true
,并在调用Dispose()
时设置为IObservable<string> source = ...;
var subscription = new SingleAssignmentDisposable();
subscription.Disposable = source.Subscribe(x =>
{
if (subscription.IsDisposed) // getting notified though I've told it to stop
return;
DoThingsWithItem(x);
if (x == "the last item I'm interested in")
subscription.Dispose();
});
。
所以:
os.path