2015-09-04 12 views
1

我有一個屬性IObservable<ServiceStatus>,應使用使用異步模式的方法按需更新。如果發生任何錯誤,應該被吞下。 statusNeedToBeUpdated是一個可觀察的事件,通知我,何時更新我的​​Property。基本上,下面的代碼確實需要做什麼:ReactiveExtension根據需要調用異步代碼

Status = statusNeedToBeUpdated 
    .Select(_ => { 
     try { 
      var task = client.ServiceStatus.GetAsync(); 
      task.Wait(); 
      return task.Result; 
     } 
     catch (Exception) { 
      return null; 
     } 
    }) 
    .Where(status => status != null); 

我覺得應該有來處理異步調用client.ServiceStatus更先進的方式:我想出了這一點:

Status = statusNeedToBeUpdated 
    .Select(async _ => await client.ServiceStatus.GetAsync()) 
    .Catch(Observable.Return(Task.Factory.StartNew(()=> (ServiceStatus)null))) 
    .Where(task => task.Result != null) 
    .Select(task => task.Result); 

此解決方案更好,但我不喜歡開始一個僅返回null的新任務。 有沒有人知道更好的解決方案。

+0

所以你想訂閱一個observable,做一些事情併發布那個東西的結果。代替此代碼,訂閱'statusNeedToBeUpdated'並用[Subject](https://msdn.microsoft.com/en-us/library/hh242970(v = vs.103).aspx)替換Status [status],其上您可以使用OnNext發佈結果 –

回答

1

在我看來,你需要這個查詢:

Status = 
    statusNeedToBeUpdated 
     .SelectMany(_ => 
      Observable 
       .FromAsync(() => client.ServiceStatus.GetAsync()) 
       .Retry()); 

這將重試隨時GetAsync拋出一個錯誤,避免了需要返回虛值或任務。

2

您可以使用Task<ServiceStatus>.FromResult(null)這將返回已完成的任務,而不是創建一個新的任務。

但是,您也可以使用Observable.FromAsync來簡化它。

Status = statusNeedToBeUpdated 
    .Select(_ => Observable.FromAsync<ServiceStatus>(async() => await client.ServiceStatus.GetAsync()) 
    .SelectMany(s=> s);