以下是我尝试使用Reactive Extensions做的一个简单示例,但它不起作用
public static void Main(string[] args)
{
var list = new List<int> { 1, 2, 3 };
var obs = list.ToObservable();
IDisposable subscription = obs.SubscribeOn(Scheduler.NewThread).Subscribe(p =>
{
Console.WriteLine(p.ToString());
Console.WriteLine(Add(obs).ToString());
},
err => Console.WriteLine("Error"),
() => Console.WriteLine("Sequence Completed")
);
Console.ReadLine();
subscription.Dispose();
}
private static int Add(IObservable<int> wholeList)
{
int sum = 0;
wholeList.ForEach(i => sum = sum + i);
return sum;
}
1
_
1
6
2
6
3
6
Sequence Completed
_
即。我想在每次迭代中执行一个方法Add(obs),其中obs本身就是正在进行迭代的冷IObservable吗?
答案 0 :(得分:2)
改变这个:
IDisposable subscription = obs.SubscribeOn(Scheduler.NewThread)
到此:
IDisposable subscription = obs.ObserveOn(Scheduler.NewThread)
你应该注意到,就Rx而言,你做的事情很糟糕。你正在进出观察者。你应该尽可能避免这种情况。
因此,例如,避免这样:
var list = new List<int> { 1, 2, 3 };
var obs = list.ToObservable();
这是相同的:
var obs = Observable.Range(1, 3);
整个static int Add(IObservable<int> wholeList)
方法也很糟糕。它调用ForEach
(通常应该警告你做错了)将值从可观察量中取出。这是可以发生死锁的地方。
已经存在一个名为Sum
的可观察扩展名,它会返回IObservble<int>
,但这并不会让您离开可观察对象。
所以尝试编写这样的代码:
var obs = Observable.Range(1, 3);
var query =
from n in obs
from s in obs.Sum()
select new
{
Number = n.ToString(),
Sum = s.ToString(),
};
using (var subscription = query.SubscribeOn(Scheduler.NewThread).Subscribe(
x =>
{
Console.WriteLine(x.Number);
Console.WriteLine(x.Sum);
},
err =>
Console.WriteLine("Error"),
() =>
Console.WriteLine("Sequence Completed")))
{
Console.ReadLine();
}
我希望这会有所帮助。
答案 1 :(得分:1)
作为你的评论,我建议你让observable根据需要生成项目,而不是在订阅后做这些事情。在您的示例中,您可以执行以下操作:
var list = new List<int> { 1, 2, 3 };
var obs = list.ToObservable().Select(i => new Tuple<int,IObservable<int>>(i,list.ToObservable()));
obs.SubscribeOn(Scheduler.NewThread).Subscribe(t => {
Console.WriteLine(t.Item1);
SaveItems(t.Item2);
});