所有对服务的调用都应通过个人频道进行。因此,所有可以访问服务器代理的方法都应该如下所示:
public async Task<SDRLocation[]> FindLocationsAsync(string searchString)
{
ChannelFactory<IQueryService> channel = new ChannelFactory<IQueryService>("SomeServ_IQuery");
channel.Open();
SomeProxy = channel.CreateChannel();
Location[] locationEntitiesFound = await SomeProxy.FindLocationsAsync(searchString);
((IChannel)SomeProxy ).Close();
return locationEntitiesFound.Select(x => new SDRLocation(x)).ToArray();
}
但是因为我有很多像这样的服务调用的方法,所以我试图避免代码重复并创建这个方法包装器:
public TResult HandleServiceCall<TResult>(Func<IPlantOrgQueryService, TResult> serviceMethod)
{
ChannelFactory<IQueryService> channel = new ChannelFactory<IQueryService>("SomeServ_IQuery");
channel.Open();
IQueryService newProxy = channel.CreateChannel();
TResult results = serviceMethod(newProxy);
((IChannel)newProxy).Close();
return results;
}
现在我希望到处都可以这样打电话:
public async Task<SDRLocation[]> FindLocationsAsync(string searchString)
{
Location[] locationEntitiesFound = await HandleServiceCall(x => x.FindLocationsAsync(searchString));
return locationEntitiesFound.Select(x => new SDRLocation(x)).ToArray();
}
但我最终得到错误“通信对象,System.ServiceModel.Channels.ClientReliableDuplexSessionChannel,因为它已被中止而不能用于通信。”
不明白什么是错误的,因为没有HandleServiceCall的方法可以正常工作......
请帮助
答案 0 :(得分:1)
TResult
的类型会让你知道什么是错的。它是Task<Location[]>
。所以你在异步调用完成之前处理代理(通过Close
)。
在调用await
之前,修复是Task
Close
,就像原始代码一样。这应该可以解决问题:
public async Task<TResult> HandleServiceCall<TResult>(Func<IPlantOrgQueryService, Task<TResult>> serviceMethod)
{
ChannelFactory<IQueryService> channel = new ChannelFactory<IQueryService>("SomeServ_IQuery");
channel.Open();
IQueryService newProxy = channel.CreateChannel();
TResult results = await serviceMethod(newProxy);
((IChannel)newProxy).Close();
return results;
}