>

Rx .NET의 Subject.OnError 를 사용하고 있습니다  예외를 전파하기보다는 던지는 것 같습니다. 내 시나리오는 주제에 별도의 스레드에 데이터가 공급되고 호출 스레드는 해당 데이터가 반환 될 때 작업을 수행해야하며 관찰 가능한 모든 데이터가 완료 될 때까지 기다려야하며 발생하는 예외가 전파됩니다.

다음은 간단한 예입니다 :

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 를 사용하여 작성되었습니다. , 전혀 사용하지 않는 것이 좋은 해결책은 아닙니다)


  • 답변 # 1

    다음은 간단한 예입니다 :

    void Main()
    {
        var subject = new Subject<bool>();
        subject.Subscribe(b => {/* bool handling code */});
        subject.OnError(new Exception()); //This call is throwing!
    }
    
    

    와이즈 비츠  과부하는 수신 된 예외를 다시 발생시킵니다. 예외를 무시하려면 다음과 같이하십시오 :

    Subscribe
    
    

    이 소스를 보려면 https://github.com/dotnet/reactive/blob/master/Rx.NET/Source/src/System.Reactive/Observable.Extensions.cs (라인 63)를 참조하십시오. ). 발견 된 예외가 발생합니다.

    <시간>

    수정:

    토끼 구멍으로 뛰어 들기를 원한다면 void Main() { var subject = new Subject<bool>(); // subject.Subscribe(); subject.Subscribe(b => {/* bool handling code */}, e => { }); subject.OnError(new Exception()); //This call is throwing! } 와 함께 호출되는 예외 처리 코드가 있습니다.  과부하 :

    .Subscribe(onNextHandlerOnly)
    
    

    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

  • 이전 matlab - 왜 로지스틱 회귀 분석 (멀티 클래스) 정확도가 그렇게 작은가?
  • 다음 java - 셀레늄 병렬 테스트 - 동일한 클래스에서 2 개의 메소드 실행