这有点棘手,但我找到的唯一方法。我希望这可以帮助别人。 这个想法是不会让异常抛出,而是创建一个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;
}
因此,现在让我们尝试遵循反弹异常。
- 在现实生活中,用户被通知并发生异常并被捕获。 (在我的示例中,我没有说明)
- 然后调用OnExceptionOccurred(Exception ex)。
- 然后使用ExceptionOccurred事件创建SendOrPostCallback,然后对当前SynchronizationContext执行Post操作。
- 为ExceptionOccurred注册的WPF应用程序(现在如果您喜欢,您可以在这里处理异常消息...我选择使用两个路径作为异常而不是三个)。它会投射和抛出异常。
- 现在,CurrentDomain_UnhandledException会对其进行处理,并向用户显示一条错误消息(就在它退出之前)。
我确定这里有很多变化,但是这确实显示了一些我在一个地方找不到的更复杂的代码。
注意:这不能解决任何通道问题。如果您有例外,您可以从中恢复,但仍然需要重新建立频道,因为它会出现故障或关闭。