1

所有对服务的调用都应通过个人渠道进行。所以所有可以访问服务器代理的方法都应该是这样的:

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 的方法工作得很好......

请帮忙

4

1 回答 1

1

的类型TResult会让你知道出了什么问题。是Task<Location[]>。因此,您在Close异步调用完成之前处理代理(通过)。

解决方法是await调用Taskbefore 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;
}
于 2013-02-18T23:54:04.257 回答