views:

218

answers:

3

I am playing with Rx in .Net3.5SP1 and trying the 101 Rx Samples. I am trying the first sample (Start - Run Code Asynchronously) but it doesn't seem to actually run asynchronously. For example,

        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]");

Outputs

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

Is there an explanation for this? Am I doing something wrong? Is this expected behaviour?

UPDATE

I would have thought it would have said

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

But the main thread is blocked while the supposedly Asynch call happens.

+1  A: 

That looks reasonably expected to me.

If you put a Thread.Sleep call between "Created" and "Starting" I think you'll see the "Calculating" line appear, showing that it's doing work while the main thread is running. That's the way in which it's asynchronous.

If you're concerned because First() returns the value itself, rather than giving a sort of "future" value you can consult later, that's a different matter - and I have two blog posts for you to read: part 1; part 2. I think you want the Prune method, but I'm not entirely sure.

Jon Skeet
No that's not the issue... the issue is the sequence of events. I would have thought it would have said[Creating][Created][Starting]Calculating...[Started] <...3 Second Wait...>Done. But the main thread is blocked while the supposedly Asynch call happens...
kouPhax
@kouPhax: The First() method has to *return* the value though, doesn't it? (Admittedly the value is just `Unit` in this case, but still...) This means it can't complete until *after* the calculation has finished. Basically the calculation *is* going on asynchronously, but the First() call waits for it to complete. The comment explicitly says that: "// subscribe and wait for completion of background operation"
Jon Skeet
Ha! Suppose I should learn to read! Thanks
kouPhax
+1  A: 

The line // subscribe and wait for completion of background operation says that it waits for the background operation to complete. So you wouldn't expect the code following that line (Console.WriteLine("[Started]");) to run until the the operation is completed, right?

Gabe
A: 

First is blocking ... Subscribe is what you want:

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