为什么最后没有调用我的DownloadStringAsync Observable?

时间:2011-12-13 20:22:00

标签: system.reactive

我正在使用FromEventPattern,我希望能够在我的observable的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?
       } );
  }

更新 显然我认为OnCompleted()会解决我的问题是错误的。我尝试将StartDownload更改为以下内容,但仍未调用Last。这是怎么回事?

  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 个答案:

答案 0 :(得分:1)

您需要编写以下订阅代码:

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

您的Finally调用返回一个“附加”到anobs observable的新observable - 它根本不会实际修改anobs observable。如果您直接订阅anobs,它对Finally来电一无所知,因此无法调用。

答案 1 :(得分:1)

请记住,Rx运算符与LINQ运算符完全相同,因为它们实际上并不执行任何操作,直到您对“ForEach”执行某些操作(即评估它)。在Rx中,Subscribe就像ForEach。这里的电子化是正确的(但我想进一步解释为什么他是正确的!)