【问题标题】:Possible to call WCF services from Silverlight's global UnhandledException handler?可以从 Silverlight 的全局 UnhandledException 处理程序调用 WCF 服务吗?
【发布时间】:2010-12-27 20:48:58
【问题描述】:

我正在尝试按照以下方式做一些事情:

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() 的调用。 [如果异常处理程序中我们的状态阻止了 Created -> Opened WCF 通道转换]
  • 使 service 成为 App 类的成员,并在我的 Application_Startup 处理程序中对其进行初始化。 [理论上,当 Silverlight 将 AppDomain 解开到全局异常处理程序的位置时,我用来生成 WCF 代理的帮助程序类已被拆除/处于某种不良状态]
  • 服务设为静态。 [理论上这不是同一个 App 实例,允许 service 被 GC'd]
  • 在异步调用之前验证了 service.Stateservice.EndPoint 以及我可以在调试器中快速检查的任何其他公共属性是否正确。李>
  • 已验证 服务 的创建、异步调用和同步打开/关闭调用都发生在主 (UI) 线程上,并且线程 ID 是恒定的 [no partial/"stealth " 在我的处理程序被调用之前的拆解]。
  • 将调用移至 Application_UnhandledException 之外的 service.LogErrorAsync()。 [以防其他地方配置错误]它完美无缺。

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

【问题讨论】:

    标签: wcf silverlight exception-handling


    【解决方案1】:

    愚蠢的问题...如果您的应用程序刚刚崩溃,为什么要尝试像 Web 服务调用这样危险的事情?

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

    另外,鉴于您正在执行异步调用,而不是重新启动应用程序,您基本上已经获得了竞争条件。这很糟糕。 因此,要么“冷记录”它(我最初的建议),要么等到异步调用返回/失败,然后重新启动应用程序。

    【讨论】:

    • 我希望有一种方法可以在 Silverlight 中进行同步调用,但没有。您甚至不能使用 ManualResetEvent.WaitOne() 来伪造它——在 UI 线程上调用服务完成处理程序,因此您将死锁。调用 Close() 是我所知道的最好的解决方法。 ///// 我非常喜欢 ISO 的想法。这可能就是我将要使用的...希望我们不需要记录任何 IsolatedStorageExceptions :)
    • 是的,如果用户有意将您的 IsoStore 配额更改为 0MB,您实际上可能会收到 IsoStore 异常。因此,在写入 IsoStore 之前,请检查您是否还有合理的存储空间(5kb?)。
    【解决方案2】:

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

    【讨论】:

    • 好主意——但我选择了贾斯汀的,因为它更容易实施。
    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 2011-10-13
    相关资源
    最近更新 更多