2013-07-25 27 views
0

我有類似是否正確扔OperationCanceledException內Observable.FromAsync

observable.Select(x => Observable.FromAsync(token => Task.Run(() => 
{ 
    // ... do some work ... 

    token.ThrowIfCancellationRequested(); 

    // ... do some more work ... 

    return 7 * x; 
}, token))) 
.Switch() 
.Subscribe(x => 
{ 
    // Whatever 
}); 

Task內可以發生一個需要一段時間工作的一些代碼,所以如果Switch已經轉移到另一個任務(因爲新的價值抵達observable)我想放棄做這項工作。

撥打ThrowIfCancellationRequested()是否正確?即一旦從FromAsync返回IObservable已被處置(並取消令牌),我的OperationCanceledException將被忽略 - 或者它會導致其他地方的問題?

我在一個測試應用程序嘗試了這一點,似乎就ok了工作 - 但是,這並不意味着它是正確的:)

回答

1

在底層,task.ToObservable()最終調用。 ToObservable增加了一個延續到最後也做這個任務:這意味着可觀察會失敗,TaskCanceledException

switch (task.Status) 
{ 
case TaskStatus.RanToCompletion: 
    subject.OnNext(Unit.Default); 
    subject.OnCompleted(); 
    return; 
case TaskStatus.Canceled: 
    subject.OnError(new TaskCanceledException(task)); 
    return; 
case TaskStatus.Faulted: 
    subject.OnError(task.Exception.InnerException); 
    return; 
default: 
    return; 
} 

。但在你的代碼發生這種情況時,沒有觀察者觀察到AsyncSubject,所以沒有任何反應。所以它似乎沒問題。