简体   繁体   English

从 rx.net Observable.FromAsync 捕获异常

[英]Catch exception from rx.net Observable.FromAsync

I have the following Reactive Extensions Subject and need to log exceptions, and also shutdown this potentially blocking async task created on Observable.FromAsync cleanly.我有以下 Reactive Extensions Subject并且需要记录异常,并且还干净地关闭在Observable.FromAsync上创建的这个可能阻塞的异步任务。

In relation to this and on cancelling the token, the exception TaskCanceledException would be thrown by anything waiting on the token.与此相关并在取消令牌时,任何等待令牌的东西都会抛出异常TaskCanceledException

How can i trap these exceptions - ignoring the TaskCanceledException as that is expected on shutdown, and logging the rest?我如何捕获这些异常 - 忽略关机时预期的TaskCanceledException ,并记录其余异常?

internal sealed class TradeAggregator : IDisposable
{
    private readonly Subject<TradeExecuted> feed = new();
    private readonly CancellationTokenSource cts = new();
    private bool isStopped;
    private bool isDisposed;

    public TradeAggregator(Func<TradeAggregate, CancellationToken, Task> dispatch)
    {
        feed
            .GroupByUntil(x => (x.Execution.Contract.Symbol, x.Execution.AccountId, x.Tenant, x.UserId), x => Observable.Timer(TimeSpan.FromSeconds(5)))
            .SelectMany(x => x.ToList())
            .Select(trades => Observable.FromAsync(() => dispatch(AggregateTrades(trades), cts.Token)))
            .Concat() // Ensure that the results are serialized.
            .Subscribe(cts.Token); // Check status of calls.
    }

    private TradeAggregate AggregateTrades(IEnumerable<TradeExecuted> trades)
    {
        // Do stuff.
        return new TradeAggregate();
    }

    public void OnNext(ExecutedTrade trade) => this.feed.OnNext(trade);

    public void Stop()
    {
        if (isStopped) return;
        isStopped = true;
        cts.Cancel();
    }

    public void Dispose()
    {
        if (isDisposed) return;
        isDisposed = true;
        
        Stop();
        feed.Dispose();
        cts.Dispose();
    }
}

Use a different Subscribe overload:使用不同的Subscribe重载:

    feed
        .GroupByUntil(x => (x.Execution.Contract.Symbol, x.Execution.AccountId, x.Tenant, x.UserId), x => Observable.Timer(TimeSpan.FromSeconds(5)))
        .SelectMany(x => x.ToList())
        .Select(trades => Observable.FromAsync(() => dispatch(AggregateTrades(trades), cts.Token)))
        .Concat() // Ensure that the results are serialized.
        .Subscribe(
          x => {}, //OnNext, do nothing
          e => {  //OnError, handle
            if(e.GetType() == typeof(TaskCanceledException))
              ; //ignore
            else
            {
              ; //log
            }
          },
          cts.Token
        );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM