代码之家  ›  专栏  ›  技术社区  ›  James Hughes

Net 3.5中的Rx不是异步的?

  •  5
  • James Hughes  · 技术社区  · 15 年前

    我正在玩.Net3.5SP1中的Rx并尝试 101 Rx Samples

            Console.WriteLine("[Creating]");
            var o = Observable.Start(() => 
            {
                Console.WriteLine("Calculating..."); 
                Thread.Sleep(3000); 
                Console.WriteLine("Done."); 
            });
            Console.WriteLine("[Created]");
            Console.WriteLine("[Starting]");
            o.First();   // subscribe and wait for completion of background operation
            Console.WriteLine("[Started]");
    

    输出

    [Creating]
    [Created]
    [Starting]
    Calculating...
        <...3 Second Wait...>
    Done.
    [Started]
    

    对此有何解释?我做错什么了吗?这是预期的行为吗?

    我本以为它会说

    [Creating] 
    [Created] 
    [Starting] 
    Calculating... 
    [Started] 
        <...3 Second Wait...> 
    Done. 
    

    但是,当假定的异步调用发生时,主线程被阻塞。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Jon Skeet    15 年前

    这在我看来是合理的。

    如果你把 Thread.Sleep 在“Created”和“Starting”之间调用,我想您会看到“computing”行出现,显示它在主线程运行时正在工作。这就是异步的方式。

    如果你担心是因为 First() 返回值本身,而不是给出一种“未来”值,你可以稍后参考,这是另一回事-我有两篇博文供你阅读: part 1 ; part 2 认为 你想要 Prune 方法,但我不完全确定。

        2
  •  1
  •   Gabe Timothy Khouri    15 年前

    线路 // subscribe and wait for completion of background operation 表示它等待后台操作完成。因此,您不会期望代码遵循这一行( Console.WriteLine("[Started]");

        3
  •  1
  •   Richard Anthony Hein    15 年前

    首先是阻止。。。订阅是您想要的:

            public static void Main(string[] args) {
    
            Console.WriteLine("[Creating]");
            var o = Observable.Start(() =>
            {
                Console.WriteLine("Calculating...");
                Thread.Sleep(3000);
    
            });
            Console.WriteLine("[Created]");
            Console.WriteLine("[Starting]");
    
            o.Subscribe(_ => Console.WriteLine("Done."));   // subscribe and wait for completion of background operation 
    
            Console.WriteLine("[Started]");
    
            Console.ReadKey();
        }