WCF 客户端代理在被 hangfire 工作人员服务使用时陷入故障状态
Posted
技术标签:
【中文标题】WCF 客户端代理在被 hangfire 工作人员服务使用时陷入故障状态【英文标题】:WCF Client Proxy stuck in faulted state when being used by hangfire worker services 【发布时间】:2021-12-17 10:43:50 【问题描述】:编辑 - 现在使用 WCF 客户端代理创建移出 DI 并进入 CustomerUpdateProcessor
using (OperationContextScope scope = new OperationContextScope(starClient.InnerChannel))
AddHeaders(appSettings, fordHeader, dcs, token);
var message = new ProcessMessage()
payload = customerPayload
;
task = starClient.ProcessMessageAsync(null, message);
var result = await task;
return result.ProcessMessageResponse.payload;
如果有人可以推荐一种处理方式,仍然希望它与 DI 一起工作
我有一个 .NET5.0 应用程序。它使用hangfire来触发重复性工作
每个循环作业都会创建一个 WCF 客户端代理以连接到 SOAP 服务和 ProcessMessages。
我面临的问题是,当 WCF 代理创建时,它陷入故障状态,因此无法再使用。我尝试调用 _client.Abort()
,但随后发生的只是错误消息更改为 @ 987654324@
我正在使用microsoft.extensions.dependencyinjection
注册我的所有服务,包括容器中的临时代理,如下所示:
服务注册
public static IServiceCollection AddCustomerUpdate(this IServiceCollection services, IConfigurationRoot config)
services.AddTransient<ICustomerUpdateService, CustomerUpdateService>();
services.AddTransient<ICustomerUpdateProcessor, CustomerUpdateProcessor>();
services.AddTransient<IDmsCustomerUpdateMessageService, DmsCustomerUpdateMessageService>();
services.AddCustomerUpdateClient(config);
return services;
public static IServiceCollection AddCustomerUpdateClient(this IServiceCollection services, IConfigurationRoot config)
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
| SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
BasicHttpsBinding binding = new BasicHttpsBinding()
SendTimeout = TimeSpan.FromMinutes(1),
OpenTimeout = TimeSpan.FromMinutes(1),
CloseTimeout = TimeSpan.FromMinutes(1),
ReceiveTimeout = TimeSpan.FromMinutes(10),
Namespace = "http://www.starstandards.org/webservices/2005/10/transport",
//HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
TextEncoding = System.Text.Encoding.UTF8,
//MessageEncoding = WSMessageEncoding.Text,
UseDefaultWebProxy = true,
;
binding.MaxReceivedMessageSize = 50000000;
binding.ReaderQuotas.MaxArrayLength = 50000000;
binding.ReaderQuotas.MaxStringContentLength = 50000000;
binding.ReaderQuotas.MaxNameTableCharCount = 50000000;
var endpointConfig = config.GetSection(nameof(EndPointConfig));
EndpointAddress endpointAddress = new EndpointAddress($"endpointConfig[nameof(EndPointConfig.CuUrl)]");
var starClient = new CustomerUpdateStarTransportPortTypesClient(binding, endpointAddress);
services.AddTransient(x => starClient);
return services;
服务执行
然后,在每次执行 hangfire RecurringJob 时,它都会调用 ICustomerUpdateProccesor 并循环处理每个客户的更新列表。为此,应使用 WCF 客户端代理的单个实例
public class CustomerUpdateProcessor : ICustomerUpdateProcessor
private readonly ICustomerRepository _customerRepository;
private readonly ICustomerIntegrationRepository _customerIntergrationRepository;
private readonly IDmsCustomerUpdateMessageService _dmsCustomerUpdateMessageService;
private readonly ICustomerUpdateService _customerUpdateService;
private readonly IFordOauthService _authService;
private readonly IIntegrationRepository _integrationRepository;
public CustomerUpdateProcessor(
ICustomerIntegrationRepository customerIntegrationRepository,
ICustomerRepository customerRepository,
IDmsCustomerUpdateMessageService dmsCustomerUpdateMessageService,
ICustomerUpdateService customerUpdateService,
IFordOauthService authService,
IIntegrationRepository integrationRepository
)
_authService = authService;
_customerIntergrationRepository = customerIntegrationRepository;
_integrationRepository = integrationRepository;
_customerRepository = customerRepository;
_dmsCustomerUpdateMessageService= dmsCustomerUpdateMessageService;
_customerUpdateService = customerUpdateService;
[DisableConcurrentExecution(3600)]
[AutomaticRetry(Attempts = 0)]
public async Task ProcessUpdatesForActiveCustomersAsync()
var customers = _customerRepository.GetAllCustomers();
foreach (var customer in customers)
var integrations = _customerIntergrationRepository.GetIntegrationsForCustomer(customer.Id);
foreach (var integration in integrations)
if (integration.Name == "Xfi.CustomerUpdate" && integration.Enabled)
var integrationParams = integration.Paramaters;
var dealerCode = integrationParams.Single(x => x.Name == "DealerCode").Value;
var appArea = new ApplicationAreaModel()
DealerCode = dealerCode
;
var messages = await _dmsCustomerUpdateMessageService.GetMessagesAsync(customer.ServerAddress, appArea);
if (messages != null)
foreach (var message in messages)
var cuMessage = message as CustomerUpdateMessage;
var builder = new ProcessCustomerInformationBuilder();
builder.AddApplicationArea(cuMessage.ApplicationArea);
builder.AddHeader();
if (cuMessage.CustomerModel is IndividualCustomerModel)
builder.AddIndivualCustomer(cuMessage.CustomerModel as IndividualCustomerModel);
else
builder.AddSpecifiedOrganization(cuMessage.CustomerModel as BusinessCustomerModel);
var payload = builder.BuildPayload();
var token = await GetAccessTokenAsync(integrationId: integration.Id);
var appsettings = new ApplicationSetttings()
XmotiveAppId = ""
;
await _customerUpdateService.ProcessCustomerUpdateAsync(payload, dealerCode, appsettings, token.ToString(), customer.Name);
肥皂服务
在此处理器中,ICustomerUpdateService 用于调用 WCF 客户端代理并调用 SOAP 服务。
public class CustomerUpdateService : StarService, ICustomerUpdateService
private readonly CustomerUpdateStarTransportPortTypesClient _starClient;
private readonly IServiceProvider _serviceProvider;
public CustomerUpdateService(CustomerUpdateStarTransportPortTypesClient starClient, IServiceProvider serviceProvider)
_starClient = starClient;
_serviceProvider = serviceProvider;
[OperationContract]
public async Task<AcknowledgeCustomerInformationPayload> ProcessCustomerUpdateAsync(
ProcessCustomerInformationPayload customerPayload,
string siteCode,
ApplicationSetttings appSettings,
string token,
string customerName
)
var fordHeader = new FordDealerIdentity()
SiteCode = siteCode
;
DataContractSerializer dcs = new DataContractSerializer(typeof(FordDealerIdentity));
Task<ProcessMessageResponse1> task;
using (OperationContextScope scope = new OperationContextScope(_starClient.InnerChannel))
AddHeaders(appSettings, fordHeader, dcs, token);
var message = new ProcessMessage()
payload = customerPayload
;
task = _starClient.ProcessMessageAsync(null, message);
var result = await task;
return result.ProcessMessageResponse.payload;
使用(OperationContextScope scope = new OperationContextScope(_starClient.InnerChannel))
在这一行抛出错误
它抛出错误“对象不能被用作其处于故障状态”
问题似乎与多线程和 WCF 客户端代理有关,但我不确定如何正确处理和遇到 WCF 的 .NETCores 端口和System.ServiceModel.Primitives
中缺少功能的障碍@
【问题讨论】:
也许你可以从这个链接找到解决方案:***.com/questions/9409329/… 通过将 WCF 客户端代理创建移出 DI 并进入包装在使用中的服务本身来解决我的问题 更新了问题 【参考方案1】:也许你可以试试try...catch
而不是using
声明
【讨论】:
以上是关于WCF 客户端代理在被 hangfire 工作人员服务使用时陷入故障状态的主要内容,如果未能解决你的问题,请参考以下文章