2013-04-23 62 views
0

我对Rx相当新,并且无法找到解决方案来解决我的问题。我正在使用Rx通过客户端库开始下载。目前,它看起来像:缓冲订阅的无功扩展

private void DownloadStuff(string descriptor, Action<Stuff> stuffAction) 
{ 
    this.stuffDownloader.GetStuffObservable(descriptor).Subscribe(x => stuffAction(x)) 
} 

where stuffDownloader是在客户端库中定义的下载逻辑的包装。但是我遇到了一个问题,那就是我太多地调用了DownloadStuff,导致很多下载,并且压倒了系统。现在我想要做的是

private void DownloadStuff(string descriptor, Action<Stuff> stuffAction) 
{ 
    this.stuffDownloader.GetStuffObservable(descriptor) 
     .SlowSubscribe(TimeSpan.FromMilliSeconds(50)) 
     .Subscribe(x => stuffAction(x)) 
} 

其中,SlowSubscribe是Rx操作的一些组合,仅在某个时间间隔订阅。

通常我会将这些DownloadStuff调用放在一个队列中并在一段时间内关闭它们,但最近我一直试图通过Rx做更多的事情。我发现了三种解决方案:

  1. 此功能存在,并且可以在订阅端完成。
  2. 这是可能的,但下载器的基础设施是不正确的,应该改变(即stuffDownloader需要有不同的行为)
  3. 这不应该与Rx,做另一种方式。

发生在我身上#2可能通过将IObservable的描述符传递给客户端库,并以某种方式减慢描述符进入Observable的方式。

+0

你真正的问题是什么? – 2013-05-22 19:05:59

回答

-1

您可能理论上使用Rx将您的请求视为事件。这样你可以利用Rx的序列化特性来排队下载。

我会认为你的网络层(或stuffDownloader)会为你做这个,但如果你想加入我的黑客....这就是我已经提出(Yeehaw !!)

1. 不要通过一个动作,使用Rx!你基本上失去了这里的错误处理,并设置了自己的奇怪的未处理的异常。

private void DownloadStuff(string descriptor, Action<Stuff> stuffAction) 

成为

private IObservable<Stuff> DownloadStuff(string descriptor) 

2. 现在我们只是有一个方法调用另一个。似乎毫无意义。扔掉抽象。

3. 修复底层。对我来说stuffDownloader并没有做它的工作。更新接口以采用IScheduler。现在,你可以通过它的专用EventLoopScheduler执行工作

public IObservable<Stuff> GetStuffObservable(string descriptor, IScheduler scheduler) 

4. 修复的执行序列化? 正如你想序列化你的请求(HMMM ....),你可以让电话同步。

private Stuff GetSync(string description) 
{ 
    var request = (HttpWebRequest)WebRequest.Create("http://se300328:90/"); 
    var response =request.GetResponse(); 
    var stuff = MapToStuff(response); 
    return stuff; 
} 

现在,你只需要调用,在你其他的方法

public IObservable<Stuff> GetStuffObservable(string descriptor, ISchedulerLongRunning scheduler) 
{ 
    return Observable.Create<Stuff>(o=> 
     { 
      try 
      { 
       var stuff = GetStuff(description); 
       o.OnNext(stuff); 
       o.OnCompleted(); 
      } 
      catch(Exception ex) 
      { 
       o.OnError(ex); 
      } 
      return Disposable.Empty(); //If you want to be sync, you cant cancel! 
     }) 
     .SubscribeOn(scheduler); 
} 

然而,成就了这一切,我敢肯定这是不是你真正想要的。我希望在系统的其他地方出现问题。

另一种选择是考虑使用合并运算符,它是最大的concurent功能?

+0

很好的建议,但不是一个答案。这个问题很模糊,但他们需要帮助,“我打电话给DownloadStuff太多了,导致很多下载,并且压倒了系统。” – 2013-05-22 19:08:56

+0

是的,它似乎并不像用户对答案很感兴趣,或者澄清他们的问题。 – 2013-05-23 14:50:41