2014-10-18 58 views
1

我目前正在使用ReactiveUI(在使用Rx之前有過一些經驗)。 我想要做的是處理某種形式的火災/遺忘/通知工作流程。使用ReactiveUI進行掃描並忘記

基本上,我想要執行和操作,然後在成功或失敗時通知。不過,我不想等待行動做下一個之前完成,所以我實現下面的代碼片段:

private ReactiveList<VerifiableString> _inputData = new ReactiveList<VerifiableString>(); 
    private ReactiveList<VerifiableString> _savedData = new ReactiveList<VerifiableString>(); 

    private Subject<VerifiableString> _stringSubject = new Subject<VerifiableString>(); 

    private ReactiveCommand<Unit> _addCommand; 

    public MainViewModel() 
    { 
     for (int i = 0; i < 10; i++) 
     { 
      _inputData.Add(new VerifiableString{Value = Guid.NewGuid().ToString()}); 
     } 

     var canExecute = this.WhenAny(x => x.InputData.Count, x => x.Value != 0); 

     AddCommand = ReactiveCommand.CreateAsyncTask(canExecute, x => SendStringForProcessingAsync()); 
     AddCommand.ThrownExceptions.Subscribe(ex => MessageBox.Show(ex.ToString())); 

     _stringSubject.ObserveOn(RxApp.MainThreadScheduler).Subscribe(AddString, e => MessageBox.Show(e.Message)); 
    } 

    private async Task<Unit> SendStringForProcessingAsync() 
    { 
     var item = InputData.First(); 
     InputData.RemoveAt(0); 
     //intentionally not awaiting on this 
     PostNewItemAsync(item); 
     return new Unit(); 
    } 

    private async Task PostNewItemAsync(VerifiableString item) 
    { 
     _stringSubject.OnNext(item); 
     await Task.Delay(1000); 
     item.Verified = true; 
     _stringSubject.OnNext(item); 
    } 

此代碼的工作,我希望它。我可以根據需要多次調用該命令,並立即通知該命令已被調用,然後1秒後通知該命令已完成。

我有一種感覺,雖然,通過使用ReactiveCommand和主題,我可能會丟失ReactiveUI的地步?另外,通過使用這個主題,我沒有得到直接使用ReactiveCommands獲得的那個可愛的ThrownError觀察值。

對於背景下,UI包含兩個列表和一個按鈕,點擊按鈕從一個列表移動的到另一個字符串,一秒鐘後,該字符串與「驗證」標誌更新。

編輯20141023

所以現在我有這樣的:

{ 
    //... 
    AddCommand 
     .SelectMany(_ => Observable.FromAsync(SendStringForProcessingAsync)) 
     .Catch(Observable.Return(new VerifiableString{Value = "What the hell !"})) 
     .ObserveOn(RxApp.MainThreadScheduler) 
     .Subscribe(AddString); 

    AddCommand.ThrownExceptions.Subscribe(ex => Debug.WriteLine(ex)); 
    //... 
} 

private async Task<VerifiableString> PostNewItemAsync(VerifiableString param, CancellationToken cancellationToken) 
{ 
    await Task.Delay(_random.Next(1000, 5000), cancellationToken); 
    param.Verified = VerifyState.Verified; 
    return param; 
} 


private async Task<VerifiableString> SendStringForProcessingAsync(CancellationToken t) 
{ 
    var item = InputData.First(); 
    InputData.RemoveAt(0); 
    AddString(item); 
    return await PostNewItemAsync(item, t); 
} 

如果我拋出的異常的「SendStringForProcessingAsync」,我的「錯誤消息」我的列表中出現(雖然沒有出現在調試日誌)。但是,在這一點上,我不能再繼續執行命令。

此外,我使用Observable.FromAsync,因此我可以傳入取消標記並取消在飛行中的項目。我不能爲我的生活雖然弄清楚如何訪問CancellationTokenSource這樣我就可以取消這些東西......

我錯過了一些東西明顯?

回答

1

如果你想退出RxCmd的單item'ing的,你做這樣的事情(左,因爲適當的仿製藥編碼,通過-文本區域):

AddCommand = ReactiveCommand.Create(); 

AddCommand 
    .SelectMany(_ => DoSomethingAsync() 
     .Catch(ex => { log.write("Crap."); return Observable.Empty(); })) 
    .Subscribe(x => log.write("It worked!");