2013-06-04 1 views
0

그리고 사용자에게 어떻게 표시 할 수 있습니까? 이 게시물 : WCF Duplex: How to handle thrown exception in duplex Callback 내 시나리오에 매우 가깝습니다. 이 게시물은 채널에 오류가 발생했을 때 연결을 다시 설정할 수 있도록 도와줍니다.이중 채널 콜백은 예외를 throw하는 메서드를 호출합니다. 집행은 어디로 가나 요?

게시 응용 프로그램 Pub 및 구독중인 WPF 응용 프로그램 Sub가 있습니다. Pub에서 메시지를 보내고 Sub는 이중 채널을 사용하여 콜백에 가입했습니다.
Sub.ViewModel.ReactToChange(sender, e)은 일부 데이터를 읽으려고 시도하지만 예외를 throw 할 수 없으며 예외를 throw합니다.

DispatcherUnhandledException (나는 정말 그것을 기대하지 않았다.) 그것을 잡을하지 않습니다
AppDomain.CurrentDomain.UnhandledException (즉 나를 놀라게 않습니다)
최종 결과를 잡을 수 없습니다입니다 난 여전히 실행중인 응용 프로그램을 가지고, 사용자에게 예외 메시지가 표시되지 않으므로 문제를 해결할 수 있습니다. 그 예외를 사용자에게 보여줄 수있는 방법이 있습니까?

답변

0

이것은 약간 까다 롭지만 내가 찾은 유일한 방법입니다. 나는 이것이 다른 사람들을 돕기를 바랍니다. 아이디어는 예외를 던지게하는 대신 UnhendledExceptionEventArg를 만들고 UI 레이어에 전달하는 것입니다. 다음은 몇 가지 예제 코드입니다.

public class BuggySubscriber : IDisposable 
{ 
    public BuggySubscriber(string dataSourceName) 
    { 
     SyncContext = SynchronizationContext.Current; 
     Subscriber = new MockSubscriber(dataSourceName); 
     Subscriber.Refreshed += OnDataChanged; 
    } 

    public SynchronizationContext SyncContext { get; set; } 

    public event EventHandler<UnhandledExceptionEventArgs> ExceptionOccurred; 

    // Bouncing Exception Step 3 
    private void OnExceptionOccured(Exception ex) 
    { 
     var callback = new SendOrPostCallback(delegate 
      { 
       var handler = ExceptionOccurred; 
       if (!ReferenceEquals(handler, null)) 
        handler(this, new UnhandledExceptionEventArgs(ex, true)); 
      }); 

     SyncContext.Post(callback, null); 
    } 

    void OnDataChanged(object sender, ServiceModel.DataChanged.DataChangedEventArgs e) 
    { 
     // Bouncing Exception Step 1 & 2 
     OnExceptionOccured(new NotImplementedException()); 
    } 

따라서 "Sub"코드입니다. WPF 응용 프로그램에서 응용 프로그램을 시작할 때 다음을 추가합니다.

 protected override void OnStartup(StartupEventArgs e) 
     { 
      AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; 
      BuggySubscriber.ExceptionOccurred += Sub_ExceptionOccurred; 
... 
     } 

     // Bouncing Exception Step 5 
     void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
     { 
      var exception = e.ExceptionObject as Exception; 
      if (!ReferenceEquals(exception, null)) 
       ShowErrorMessage(exception); 
     } 

     // Bouncing Exception Step 4 
     void Sub_ExceptionOccurred(object sender, UnhandledExceptionEventArgs e) 
     { 
      var exception = e.ExceptionObject as Exception; 
      if (!ReferenceEquals(exception, null)) 
       throw exception; 
     } 

이제는 튀는 예외를 따르려고합니다.

  1. 실생활에서 구독자에게 알림이 전송되고 예외가 발생하여 캐치되었습니다. (내 견본에서는이를 보여주지 않습니다.)
  2. 그러면 OnExceptionOccurred (Exception ex)가 호출됩니다.
  3. 그런 다음 ExceptionOccurred 이벤트를 사용하여 SendOrPostCallback을 만든 다음 현재 SynchronizationContext에 게시합니다.
  4. ExceptionOccurred에 등록 된 WPF 응용 프로그램 (원하는 경우 여기에서 예외 메시지를 처리 ​​할 수 ​​있습니다 ... 나는 3 개가 아닌 2 개의 경로를 사용하기로 결정했습니다.) Exception을 던지고 예외를 throw합니다.
  5. 이제 CurrentDomain_UnhandledException이이를 처리하고 사용자에게 종료하기 바로 전에 오류 메시지를 표시합니다.

이렇게 많은 변형이있을 것이라고 확신하지만, 한 곳에서 찾을 수없는 까다로운 코드를 보여줍니다.
참고 : 채널 문제는 해결되지 않습니다. 복구 할 수있는 예외가있는 경우 오류가 있거나 닫히기 때문에 채널을 다시 설정해야합니다.

관련 문제