Одноразовый объект, возвращаемый методами расширения Subscribe
, возвращается исключительно для того, чтобы позволить вам вручную отказаться от подписки на наблюдаемый объект до естественного завершения наблюдаемого.
Если наблюдаемое завершается — либо с OnCompleted
, либо с OnError
— тогда подписка уже готова для вас.
Попробуйте этот код:
var xs = Observable.Create<int>(o =>
{
var d = Observable.Return(1).Subscribe(o);
return Disposable.Create(() =>
{
Console.WriteLine("Disposed!");
d.Dispose();
});
});
var subscription = xs.Subscribe(x => Console.WriteLine(x));
Если вы запустите приведенное выше, вы увидите, что «Disposed!» записывается в консоль, когда наблюдаемое завершается без необходимости вызова .Dispose()
для подписки.
Следует отметить одну важную вещь: сборщик мусора никогда не вызывает .Dispose()
для наблюдаемых подписок, поэтому вы должны удалять свои подписки, если они не завершились (или могли не закончиться) естественным образом до того, как ваша подписка выйдет из области действия.
Возьмите это, например:
var wc = new WebClient();
var ds = Observable
.FromEventPattern<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs>(
h => wc.DownloadStringCompleted += h,
h => wc.DownloadStringCompleted -= h);
var subscription =
ds.Subscribe(d =>
Console.WriteLine(d.EventArgs.Result));
Наблюдаемый объект ds
будет присоединяться к обработчику событий только тогда, когда у него есть подписка, и будет отсоединяться только после завершения наблюдаемого объекта или удаления подписки. Поскольку это обработчик событий, наблюдаемый никогда не завершится, потому что он ожидает большего количества событий, и, следовательно, удаление — единственный способ отсоединиться от события (для приведенного выше примера).
Когда у вас есть наблюдаемая FromEventPattern
, которая, как вы знаете, когда-либо вернет только одно значение, разумно добавить метод расширения .Take(1)
перед подпиской, чтобы позволить обработчику событий автоматически отсоединяться, и тогда вам не нужно вручную удалять подписку.
Вот так:
var ds = Observable
.FromEventPattern<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs>(
h => wc.DownloadStringCompleted += h,
h => wc.DownloadStringCompleted -= h)
.Take(1);
Надеюсь, это поможет.
person
Enigmativity
schedule
10.10.2011