Я играю с Rx в.Net3.5SP1 и пробую 101 Образец Rx. Я пробую первый образец (Запустите - Код Выполнения Асинхронно), но это, кажется, на самом деле не работает асинхронно. Например,
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.
Но основной поток заблокирован, в то время как, предположительно, Асинхронный вызов происходит.
На мой взгляд, этого можно было ожидать.
Если вы поместите вызов Thread.Sleep
между «Created» и «Starting», я думаю, вы увидите строку «Calculating», показывающую, что он выполняет работу, пока выполняется основной поток. Это способ асинхронности.
Если вы обеспокоены тем, что First ()
возвращает само значение, а не дает своего рода «будущее» значение, с которым вы можете ознакомиться позже, это другое дело - и у меня есть два сообщения в блоге для вам следует прочитать: часть 1 ; часть 2 . Я думаю , что вам нужен метод Prune
, но я не совсем уверен.
Строка // подписка и ожидание завершения фоновой операции
сообщает, что она ожидает завершения фоновой операции. Таким образом, вы не ожидаете, что код, следующий за этой строкой ( Console.WriteLine ("[Started]");
), будет выполняться до тех пор, пока операция не будет завершена, верно?
Во-первых, это блокировка ... Подписка - это то, что вы хотите:
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();
}