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



我正在使用FromEventPattern,我希望能够在我的可观察对象的最后块做一些清理。现在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更改为以下内容,最后仍然没有调用。这是怎么回事?

  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;
  }

您需要这样编写订阅代码:

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

你的Finally调用返回一个新的可观察对象,它被"附加"到anobs的可观察对象上——它根本没有实际修改anobs的可观察对象。如果你直接订阅anobs,它不知道Finally调用的任何信息,所以它不能被调用。

请记住,Rx操作符与LINQ操作符完全相同,因为它们实际上不做任何事情,直到您对它进行"ForEach"操作(即求值)。在Rx中,Subscribe类似于ForEach。Enigmativity在这里是正确的(但我想进一步解释一下为什么他是正确的!)

相关内容

  • 没有找到相关文章

最新更新