【问题标题】:What to do with a WCF service client in faulted state?如何处理处于故障状态的 WCF 服务客户端?
【发布时间】:2015-02-12 15:09:16
【问题描述】:

异步使用 WCF 服务。如果我无法连接到服务或发生异常,它将进入故障状态并将错误写入AsyncCompletedEventArgsError 属性。

我与服务客户端有什么关系?我无法关闭它,因为它会抛出 CommunicationObjectFaultedException。记录错误后我还需要做什么?

这是我的代码:

MyServiceClient serviceClient = new MyServiceClient();

//Close the connection with the Service or log an error
serviceClient.JustAMethod += (object sender, AsyncCompletedEventArgs args) =>
{
    if (args.Error != null)
    {
        //Log error
        ErrorHandler.Log(args.Error);
    }
    else
    {
        serviceClient.Close();
    }
};

//Call the service
serviceClient.JustAMethodAsync();

【问题讨论】:

    标签: c# wcf asynchronous


    【解决方案1】:

    您可以中止它,然后创建一个新的。这是我写的一个处理这个问题的课程的片段。当客户端处于故障状态时,它在这里触摸的所有内容都是合法的。

    if (_client.InnerChannel.State == CommunicationState.Faulted)
    {
        _client.Abort();
        _client = new TServiceClient();
    }
    

    TServiceClientSystem.ServiceModel.ClientBase<TIClientInterface> 的任何子类。

    我之所以这么写,是因为我经常遇到从 MVC4 Web 应用程序的服务器端调用 Web 服务的访问问题,而浏览器客户端通过 RDS 访问该页面。

    但是,到目前为止,上面的代码还没有被使用。由于我不明白的原因,它比总是创建一个最简单的方法有更多的访问被拒绝异常每次通话的新客户,并在之后处理。我从不费心检查故障状态,因为无论如何我从来没有将它们用于一个以上的呼叫。

    using (var cli = new Blah.Blah.FooWCFClient())
    {
        _stuff = cli.GetStuff();
    }
    

    ...当然是在 try/catch 中。如果您发现客户端缓存/中止方法有任何问题,我建议您尝试为每次调用创建一个新客户端。也许它会花费几个周期,但调用 Web 服务并然后开始担心运行时效率是很愚蠢的。那匹马离开了谷仓。

    我不知道这将如何与异步业务交互,除了关于保持简单并且不跨线程共享任何东西的模糊直觉。

    欢迎来到我的噩梦。我还没有确定我们访问问题的原因,但我怀疑事情可能对你不利。所以我希望这两个选项中至少有一个能够奏效。

    更新

    这里是一些来自我们的 XAML 应用程序的 .tt 生成的服务包装器代码。每个 Web 服务调用方法都像这样包装,并且多年来一直是防弹的。我建议基本上这样做:

    public static POCO.Thing GetThing(int thingID)
    {
        var proxy = ServiceFactory.CreateNewFooWCFClientInstance();
        try
        {
            var returnValue = proxy.GetThing(thingID);
            proxy.Close();
            return returnValue;
        }
        catch(Exception ex)
        {
            //  ***********************************
            //  Error logging boilerplate redacted
            //  ***********************************
            proxy.Abort();
            throw;
        }
    }
    

    我有一种感觉,如果您根本不重用 WCF 客户端对象也一样好。

    【讨论】:

    • 非常感谢!这正是我想要的。
    【解决方案2】:

    您无能为力。创建一个新的,让垃圾收集器收集另一个。

    【讨论】:

      猜你喜欢
      • 2011-04-02
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      相关资源
      最近更新 更多