2013-06-04 31 views
0

我该如何向用户展示它? 这篇文章:WCF Duplex: How to handle thrown exception in duplex Callback非常接近我的情况。这篇文章对于帮助我在通道出现故障时重新建立连接非常有用。引发异常的双工通道回调调用方法。执行到哪里?

我有一个发布应用程序Pub和一个订阅WPF应用程序Sub。 Pub发送一条消息,Sub已经使用双工信道订阅了一个回叫。
Sub.ViewModel.ReactToChange(sender, e)试图读取一些数据,但无法抛出异常。

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执行Post操作。
  4. 为ExceptionOccurred注册的WPF应用程序(现在如果您喜欢,您可以在这里处理异常消息...我选择使用两个路径作为异常而不是三个)。它会投射和抛出异常。
  5. 现在,CurrentDomain_UnhandledException会对其进行处理,并向用户显示一条错误消息(就在它退出之前)。

我确定这里有很多变化,但是这确实显示了一些我在一个地方找不到的更复杂的代码。
注意:这不能解决任何通道问题。如果您有例外,您可以从中恢复,但仍然需要重新建立频道,因为它会出现故障或关闭。

相关问题