如何为 WCF 客户端实现重试?

问题描述 投票:0回答:2

我有一个实现

System.ServiceModel.ClientBase<TChannel>
的 C# 客户端,用于与 SOAP API 进行通信。

我希望客户端在发生超时时自动重试请求。

我想我可以使用像 Polly 这样的库来创建具有重试策略的 HttpClient 实例。
但是,我无法弄清楚如何使用该 HttpClient 实例化 WCF 客户端。

我也不确定我是否应该使用完全不同的方法,例如创建一个

IEndpointBehavior

看起来有一个可以重写的实例方法和可以实现的静态部分方法,但是我找不到任何如何正确使用它们通过实例化的 HttpClient 来实现重试的示例或通过其他机制。

我已经搜索了
构建客户端的文档
。 有关于

使用通道工厂

的部分,但它似乎也没有提供 HttpClient 的机制。 预期异常的文档特别提到了

CreateChannel

,但该示例只是尝试/捕获客户端上的调用。 我真的不想做

ConfigureEndpoint
。 我知道我可以做到这一点,并且我知道我可以创建一个装饰器,以类似的逻辑包装所有客户端调用。我只是认为这不是正确的方法。

任何为我指明正确方向的帮助将不胜感激。

    

如果是

TimeoutException
c# wcf .net-core polly retry-logic
2个回答
2
投票
RetryOnTimeout(client => client.MethodToRetryOnTimeout());

会注册一个

HttpClient
,即
AddPolicyHandler
。它基本上覆盖了
PolicyHttpMessageHandler
DelegatingHandler
我已经有一段时间没有使用 WCF 了,但如果我没记错的话,最接近的就是客户端消息拦截器(

SendAsync

)。尽管它是可行

,但不幸的是它并不容易实现。
另一种选择是使用 Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken);

。基本上,在这里,您可以重写 IClientMessageInterceptor

 方法
,并使用触发 RealProxy
Invoke
的策略来装饰
MethodBase
Invoke
 调用。这种方法的问题是 
TimeoutException
 在 .NET Core(或其后继者)中不可用。
因此,唯一的选择是包装自己的方法调用。这个可以做吗
使用通用静态方法(在您的示例中为

CommunicationException

    或者通过创建自定义
  • RealProxy
    派生类
  • RetryOnTimeout
    
    
更新#1


ClientBase 上花了更多时间后,我遇到了 这篇迁移文章

。建议使用

class ResilientSampleClient: ClientBase<ISampleClient>, ISampleClient
{
    private readonly IRetryPolicy retryPolicy = Policy
            .Handle<TimeoutException>()
            .Or<CommunicationException>()
            .WaitAndRetry(3, _ => TimeSpan.FromSeconds(1));

    public ResilientSampleClient(): base(binding, endpointAddress) {}

    public void MethodToRetryOnTimeout()     
       => retryPolicy.Execute(base.Channel.MethodToRetryOnTimeout);     
}
代替。 我还没有测试过这段代码,但是根据迁移文档,基于
RealProxy
的解决方案
可以重写如下:

DispatchProxy


wcf客户端实例可以参考

本文档
。它详细介绍了创建客户端的详细信息。

-1
投票
这篇文章

,里面详细介绍了c#中创建实例的细节,并列出了创建客户端的步骤,看看是否对你有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.