如何处理处于故障状态的 WCF 服务客户端?

Cla*_*o P 0 c# wcf asynchronous

异步使用 WCF 服务。如果我不能连接到服务或发生异常就跑到故障状态,并将其错误写入Error的性能AsyncCompletedEventArgs

我与服务客户端有什么关系?我无法关闭它,因为它会抛出一个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();
Run Code Online (Sandbox Code Playgroud)

15e*_*153 5

您可以中止它,并创建一个新的。这是我写的处理该问题的课程的片段。当客户端处于故障状态时,它在这里触及的一切都是合法的。

if (_client.InnerChannel.State == CommunicationState.Faulted)
{
    _client.Abort();
    _client = new TServiceClient();
}
Run Code Online (Sandbox Code Playgroud)

TServiceClient是 的任何子类System.ServiceModel.ClientBase<TIClientInterface>

我写这个是因为我在从 MVC4 Web 应用程序的服务器端调用 webservices 时遇到了持续的访问问题,浏览器客户端通过 RDS 访问页面。

但是,截至目前,上述代码尚未使用。出于我不明白的原因,与为每次调用总是创建一个新客户端并在之后处理它的最简单方法相比,它具有更多的拒绝访问异常。我从不费心检查故障状态,因为无论如何我从不使用它们进行多次调用。

using (var cli = new Blah.Blah.FooWCFClient())
{
    _stuff = cli.GetStuff();
}
Run Code Online (Sandbox Code Playgroud)

...当然是尝试/捕获。如果您发现客户端缓存/中止方法有任何问题,我建议您尝试为每次调用创建一个新客户端。也许它会花费几个周期,但是调用 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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