在Silverlight中关闭并重新打开出现故障的DuplexClientBase WCF代理

时间:2010-12-17 00:14:02

标签: silverlight wcf

我们的Silverlight应用程序和我们的WCF Web服务之间的双工Net.TCP连接会定期进入故障状态 - 例如,由于瞬时网络问题,或者服务崩溃并重新启动,等等。当发生这种情况时,我想抓住这个,并重新打开连接。听起来很直白,对吧?你应该可以这样做:

private void Channel_Faulted(object sender, EventArgs e)
{
    client.CloseCompleted += (sender, e) =>
        {
            if (e.Error == null)
                client = CreateClient();
            else
                Debug.WriteLine(e.Error.ToString());
        };
    client.CloseAsync();
}

但是当我尝试在CloseCompleted处理程序中的e.Error有这个异常时:

  

通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它处于Faulted状态。

我在同一主题上尝试了很多变种,包括:

  • 在连接出现故障并且只是重新创建它之后不关闭连接。
  • 手动调用client.InnerChannel.Close()和/或client.ChannelFactory.Close()。
  • 手动调用client.InnerChannel.Dispose()和/或client.ChannelFactory.Dispose()。
  • 我现在忘记了很多其他的东西。

这些策略导致了各种错误,但没有一个正常工作,包括提到的非Silverlight解决方案,比如herehere(但对于常规CLR应用程序都是如此) ,而不是Silverlight)。当然这是一个相当简单的事情,但显然通道缓存正在阻碍我。我错过了什么?在Silverlight中执行此操作的正确方法是什么?如果这是Silverlight中的错误,那么正确的解决方法是什么?

1 个答案:

答案 0 :(得分:1)

与大多数似乎以莫名其妙的方式工作的事情一样,问题是我的错。我正在使用的实际代码(毫不奇怪,我希望)比我上面发布的简化版本复杂得多。事实证明,在我的实际代码中,在我测试的特定代码路径中,从未调用此行的等效内容:

client = CreateClient();

换句话说,客户端在抛出错误后实际上并没有重新创建,而我遇到的错误主要是因为尝试重用旧实例。对不起,大惊小怪。