Rx в .Net 3.5 не асинхронный? - PullRequest
5 голосов
/ 19 февраля 2010

Я играю с Rx в .Net3.5SP1 и пробую 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]

Есть ли объяснение этому? Я делаю что-то неправильно? Это ожидаемое поведение?

UPDATE

Я бы подумал, что сказал бы

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

Но основной поток блокируется во время предположительно асинхронного вызова.

Ответы [ 3 ]

1 голос
/ 19 февраля 2010

Строка // subscribe and wait for completion of background operation говорит о том, что ожидает завершения фоновой операции.Таким образом, вы не ожидаете, что код, следующий за этой строкой (Console.WriteLine("[Started]");), будет выполняться до тех пор, пока операция не будет завершена, верно?

1 голос
/ 01 марта 2010

Сначала блокируется ... Подпишитесь, что вы хотите:

        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();
    }
1 голос
/ 19 февраля 2010

Это выглядит вполне ожидаемым для меня.

Если вы поместите вызов Thread.Sleep между «Создано» и «Запущено», я думаю, вы увидите строку «Расчет», показывающую, что она работает во время работы основного потока. Это способ асинхронности.

Если вы обеспокоены тем, что First() возвращает само значение, а не дает своего рода "будущее" значение, к которому вы можете обратиться позже, это другой вопрос - и у меня есть два сообщения в блоге, которые вы можете прочитать: часть 1 ; часть 2 . Я думаю вы хотите метод Prune, но я не совсем уверен.

...