可以从Silverlight的全局UnhandledException处理程序调用WCF服务吗?

时间:2009-12-17 23:02:59

标签: wcf silverlight exception-handling

我正试图沿着这些方向做点什么:

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
    try
    { 
        e.Handled = true;

        var errorMessage = BuildErrorMessage(e.ExceptionObject);
        var service = new MyService(Constants.MyBinding, Constants.MyServiceUri);
        service.LogErrorAsync(errorMessage);              
        // wait awhile for the channel to flush its buffers, hard abort if it takes too long
        //service.InnerChannel.Close(new TimeSpan(0, 0, 10));
    }
    finally
    {
        RestartSilverlightApp();
    }
}

它起初工作 - 我有日志条目来证明它! - 但不可靠。调整的东西,现在我根本无法使它工作。服务器组件上的断点永远不会被击中; Fiddler表明客户端甚至从未在线路上发出HTTP请求。我尝试过的事情:

  • 将调用插入Close(),即使是超时疯狂。 [根据理论,应用程序在频道可以完成其事之前重新启动]结果:应用程序始终挂起,直到超时到期。我发现这很有趣 - 当WCF表现正常时,Close()几乎立即返回。
  • 在Application_Startup中插入对service.InnerChannel.Open()的调用。 [如果有关异常处理程序中的状态的某些内容阻止创建 - >打开WCF频道转换]
  • 使服务成为App类的成员并在Application_Startup处理程序中初始化它。 [理论上,当Silverlight将AppDomain解除到全局异常处理程序时,用于生成WCF代理的辅助类被拆除/处于某种不良状态]
  • 制作服务静态。 [理论上这不是App的相同实例,允许服务为GC]
  • 验证 service.State service.EndPoint 以及我可以在异步调用之前立即在调试器中快速检查的任何其他公共属性。
  • 验证服务的创建,异步调用和同步打开/关闭调用都在主(UI)线程上发生,并且线程ID是常量[无部分/“隐身“在我的处理程序被调用之前拆分]。
  • 将调用移至Application_UnhandledException之外的 service.LogErrorAsync()。 [万一其他地方的东西错误配置]它完美无瑕。

我不是Silverlight应用程序生命周期/体系结构的专家,也不是WCF的专家。我错过的想法?

2 个答案:

答案 0 :(得分:1)

愚蠢的问题......如果您的应用程序崩溃了,为什么尝试像网络服务电话一样冒险?

我在这种场合通常会仔细阅读的策略是:
1.在IsoStore中记录未经处理的异常 2.重新启动应用程序 3.当应用程序启动时,它会检查IsoStore异常日志是否为空。如果它不是空的 - 尝试将它们发送到服务器记录器。

另外,鉴于您正在进行异步调用而不是重新启动应用程序,您基本上会遇到竞争条件。这很糟糕。 所以要么“冷日志”(我的原始建议)或等到异步调用返回/失败然后重新启动应用程序。

答案 1 :(得分:1)

所以我不认为你的问题是愚蠢的因为我必须尝试在Silverlight应用程序的生命周期的任何时刻记录异常。但是,我想知道,如果WCF可以通过原始AJAX样式POST替换为记录异常的服务。您可以将其绑定到浏览器并使用JavaScript引擎进行调用,而不是使用WebClient或Silverlight生态系统中的其他内容。