2013-02-18 69 views
1

所有对服务的呼叫都应该通过个人频道进行。因此,这可以访问服务器代理所有的方法应该是这样的一个:如何用await包装方法调用?

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.ClientReliableDu plexSessionChannel不能用于通信,因为它已被中止。“

不明白什么是错的,因为没有HandleServiceCall方法的工作就好了... ...

请帮助

回答

1

类型的TResult会让你知道什么是错的。它是Task<Location[]>。所以你在异步调用完成之前处理代理(通过Close)。

修复方法是在致电Close之前,就像您的原始代码正在执行之前一样,awaitTask。这应该是诀窍:

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; 
} 
+0

这正是我的想法。谢谢! – 2013-02-19 14:20:26