C# 在同一IObservable订阅中访问IObservable

C# 在同一IObservable订阅中访问IObservable,c#,iterator,system.reactive,C#,Iterator,System.reactive,下面是一个简单的例子,说明我正在尝试如何使用反应式扩展,但它不起作用 在这个简单的示例中,Add不起作用 期望输出 i、 e.我想在每次迭代中执行一个方法Add(obs),其中obs本身就是在迭代过程中可观察到的冷IOB?更改此项: IDisposable subscription = obs.SubscribeOn(Scheduler.NewThread) 为此: IDisposable subscription = obs.ObserveOn(Scheduler.NewThread) 你

下面是一个简单的例子,说明我正在尝试如何使用反应式扩展,但它不起作用

在这个简单的示例中,Add不起作用 期望输出 i、 e.我想在每次迭代中执行一个方法Add(obs),其中obs本身就是在迭代过程中可观察到的冷IOB?更改此项:

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();
另外,整个
静态int Add(IObservable wholeList)
方法也不好。它调用
ForEach
(这通常应该是一个警告,表明您做错了什么),从可观察对象中提取值。这就是死锁可能发生的地方

已经有一个名为
Sum
的可观察扩展,它返回一个
iobservable
,这不会使您脱离可观察范围

因此,请尝试这样编写代码:

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();
}

<>我希望这有帮助。

< P>正如你的评论一样,我建议你可以根据需要生成项目,订阅后不要做这些事情。在您的示例中,您可以执行以下操作:

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);
});
var list=新列表{1,2,3};
var obs=list.ToObservable().Select(i=>newtuple(i,list.ToObservable());
SubscribeOn(Scheduler.NewThread).Subscribe(t=>{
控制台写入线(t.Item1);
保存项(t.Item2);
});

这是一个漂亮的答案,我接受你的观点!不幸的是,我需要使用.SubscribeOn(Scheduler.NewThread),因为这里没有说明原因。在每次迭代结束时,是否有其他方法来执行MyMethod(obs)?@Cel-我将示例代码改为使用
SubscribeOn
而不是
ObserveOn
,它仍然有效。这是一个例子,说明了当进入观察对象之外的死锁时,停留在观察对象中的工作原理,因此您应该避免调用您的
MyMethod(obs)
。我认为我应该首先发布预期的MyMethod(obs),因为Add(obs)并不能很好地模拟场景。所需的MyMethod实际上是SaveMessages(obs),因此我不想对整数求和,而是在每个消息迭代结束时,我想保存obs中包含的所有消息。我不想只在OnCompleted上保存obs中的所有元素,我需要在每次迭代结束时执行此操作?@Cel-然后将签名更改为
静态IObservable Add(IObservable wholeList)
,然后使用标准运算符或
Observable.Create(…)
,在方法内部创建(…)。您很可能在这里做错了(tm)。你能描述一下你的情况吗?你想在更高的层次上完成什么?@Paul请看我刚才添加到Enigmativity的评论。。
    var list = new List<int> { 1, 2, 3 };
    var obs = list.ToObservable();
    var obs = Observable.Range(1, 3);
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();
}
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);
});