Почему, наконец, не вызывается в моем DownloadStringAsync Observable? - PullRequest
0 голосов
/ 14 декабря 2011

Я использую FromEventPattern и хочу иметь возможность выполнить некоторую очистку в блоке finally моего наблюдаемого. Сейчас блок finally не вызывается. Насколько я понимаю, я должен вызвать OnCompleted ... где-то, но не уверен, как это реализовать. Некоторый код из моей программы Silverlight:

    public IObservable<string> StartDownload ( string uri )
    {
         WebClient wc = new WebClient();
         var o = Observable.FromEventPattern<DownloadStringCompletedEventArgs>( wc, "DownloadStringCompleted" )
                           .Select( s => s.EventArgs.Result );
         wc.DownloadStringAsync( new Uri( uri ) );

     return o;
    }



  public void TestRx ()
  {
     var anobs = StartDownload( "http://www.google.com" );

     anobs
       .Subscribe( stuff =>
       {
          // do stuff
       } );

     anobs
       .Finally( () =>
       {
          // not called?
       } );
  }

UPDATE: Очевидно мое предположение, что OnCompleted () исправит мою проблему, было неверным. Я попытался изменить StartDownload на следующее и, наконец, до сих пор не вызывается. Что здесь происходит?

  public IObservable<string> StartDownload ( string uri )
  {
     WebClient wc = new WebClient();

     var subject = new AsyncSubject<string>();

     wc.DownloadStringCompleted += ( sender, e ) => 
     {
        if ( e.Error != null )
           subject.OnError( e.Error );

        subject.OnNext( e.Result );
        subject.OnCompleted();
     };

     wc.DownloadStringAsync( new Uri( uri ) );         

     return subject;
  }

Ответы [ 2 ]

1 голос
/ 17 декабря 2011

Помните, что операторы Rx точно такие же, как операторы LINQ, в том смысле, что они на самом деле ничего не делают , пока вы не сделаете что-то для ForEach (то есть оцените это). В Rx Subscribe похоже на ForEach. Энигмативность здесь верна (но я хотел бы немного подробнее объяснить, почему почему он прав!)

1 голос
/ 14 декабря 2011

Вы должны написать свой код подписки так:

anobs
    .Finally(() =>
        {
        // will now be called. ;-)
        })
    .Subscribe(stuff =>
        {
        // do stuff
        });

Ваш Finally вызов возвращает новую наблюдаемую информацию, которая «добавляется» к наблюдаемой anobs - он ничего не делает для фактического изменения наблюдаемой anobs вообще. Если вы подпишетесь непосредственно на anobs, он ничего не знает о вызове Finally, поэтому он не может быть вызван.

...