在我看来,我对RX函数有一个非常好的“感觉” - 我使用了很多这些函数或者可以想象其他函数是如何有用的 - 但是我找不到.Prune函数的位置。我知道这是AsyncSubject的多播,但它在实际场景中如何有用呢?
编辑:理查德说,WebRequest是Prune()的一个很好的候选人。我还是不知道怎么样。让我们举一个例子 - 我想将传入的uri转换为图像:
public static IObservable<BitmapImage> ToImage(this IObservable<string> source)
{
var streams =
from wc in source.Select(WebRequest.Create)
from s in Observable
.FromAsyncPattern<WebResponse>(wc.BeginGetResponse,
wc.EndGetResponse)()
.Catch(Observable.Empty<WebResponse>())
select s.GetResponseStream();
return streams
.ObserveOnDispatcher()
.Select(x =>
{
var bmp = new BitmapImage();
bmp.SetSource(x);
return bmp;
});
}
我认为没有必要将.Prune附加到.FromAsyncPattern,因为当你调用FromAsyncPattern()(很热)时,你会“立即”订阅。
答案 0 :(得分:3)
因为was confirmed on the RX Forum Prune只是一个随从运营商。
如果您的observable有一个值并且您正在发布它,可以用一次调用替换Publish \ Connect .Prune()
根据我的经验,Prune最常见的情况是:
论坛中指出的另一个问题是,当你需要在热的可观察量(通常是第一个)上缓存特定值时。然后你使用FromEvent(...)。Take(1).Prune(),任何订阅它的人都会得到相同的保证值。这个不仅仅是“方便”,而且是实现结果的唯一简单方法。
毕竟非常有用!
答案 1 :(得分:2)
最常见的情况是源可观察性很热,可以在订阅之前完成。 AsyncSubject捕获最后一个值,并为任何未来的订户重新发送它。
修改强>
我必须检查,但我相信FromAsyncPattern
在内部使用AsyncSubject
,因此实际上已经“修剪过”。
但是,假设您正在使用其他一些没有的热源,Prune
的使用完全取决于<{1}} 的生命周期之前订阅至。如果您立即订阅,则无需IObservable
。但是,如果Prune
在订阅之前存在一段时间,则可能已经完成。
这是我的理解,作为移植了Rx但从未使用IObservable
的人。也许你应该在Rx forums上问同样的问题?你有机会被Rx团队的某个人回答。
答案 2 :(得分:1)
当我有多个需要监听任务的UI组件(例如回调)时,我也找到了一个巧妙的用途,默认情况下,冷可观察的Subscribe()会多次启动该任务在跨UI组件共享状态时,这通常不是您想要的。
我知道理查德提到了很多这些要点,但我认为这对于单次运行任务来说是一个非常理想的选择,也可以添加这个例子。
var oTask = Observable.FromAsync(() => Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
Console.WriteLine("Executed Task");
}));
//Setup the IConnectedObservable
var oTask2 = oTask.PublishLast();
//Subscribe - nothing happens
oTask2.Subscribe(x => { Console.WriteLine("Called from Task 1"); });
oTask2.Subscribe(x => { Console.WriteLine("Called from Task 2"); });
//The one and only time the Task is run
oTask2.Connect();
//Subscribe after the task is already complete - we want the results
Thread.Sleep(5000);
oTask2.Subscribe(x => { Console.WriteLine("Called from Task 3"); });