首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Subject.OnError投掷

Subject.OnError投掷
EN

Stack Overflow用户
提问于 2019-01-11 17:36:50
回答 1查看 226关注 0票数 2

我使用的是Rx .NET的Subject.OnError,它似乎是抛出而不是传播异常。我的场景是,主题是在一个单独的线程上输入数据,调用线程在返回数据时需要做一些事情,还需要等待可观察到的所有数据的完成,以及传播发生的任何异常。

下面是一个简化的示例:

代码语言:javascript
复制
class Program
{
    static async Task Main(string[] args)
    {
        var subject = new Subject<bool>();

        Task.Run(async () =>
        {
            await Task.Delay(5000);
            subject.OnError(new Exception()); //This call is throwing!
        });

        subject.Subscribe(e =>
        {
            //Do some data processing here
        });

        try
        {
            //Need to wait for observable to complete before returning to the caller
            await subject.LastOrDefaultAsync();
        }
        catch
        {
            //Do some logging, clean up resources
            throw;
        }
    }
}

如果我删除对subject.Subscribe()的调用,代码就会像您预期的那样工作,并且异常将在subject.LastOrDefaultAsync()上重新抛出。但是,有了Subscribe,对subject.OnError()的调用马上就会重新抛出异常(而不是将它传递给可观察的),这对我来说是完全奇怪的。

我如何解决这个问题?

(FYI,大量的代码已经使用Subject编写了,所以建议我根本不使用它是一个不可接受的解决方案)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-11 20:35:41

下面是一个简单的例子:

代码语言:javascript
复制
void Main()
{
    var subject = new Subject<bool>();
    subject.Subscribe(b => {/* bool handling code */});
    subject.OnError(new Exception()); //This call is throwing!
}

Subscribe重载重新抛出它接收到的异常。如果要忽略这些异常,请执行以下操作:

代码语言:javascript
复制
void Main()
{
    var subject = new Subject<bool>();
    // subject.Subscribe();
    subject.Subscribe(b => {/* bool handling code */}, e => { });
    subject.OnError(new Exception()); //This call is throwing!

}

如果您想看到这个源,请在这里查看:https://github.com/dotnet/reactive/blob/master/Rx.NET/Source/src/System.Reactive/Observable.Extensions.cs (第63行)。它会抛出任何捕获的异常。

编辑

如果您想跳进兔子洞,下面的异常处理代码(实际上)会被.Subscribe(onNextHandlerOnly)重载调用:

代码语言:javascript
复制
void Main()
{
    var subject = new Subject<bool>();
    subject.Subscribe(b => b.Dump(), e => { e.Throw(); }, () => {});
    subject.OnError(new Exception()); //This call is throwing!

}

public static class X
{
    public static void Throw(this Exception exception)
    {
         System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(exception).Throw();
    }
}

EDI.Capture调用使它看起来像是异常的“源”是OnError调用,而不是Subscribe

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54151477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档