【问题标题】:How to wrap method calls with await?如何用等待包装方法调用?
【发布时间】:2013-02-19 07:54:04
【问题描述】:

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

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

请帮忙

【问题讨论】:

    标签: c# methods proxy wrapper async-await


    【解决方案1】:

    TResult 的类型会让你知道出了什么问题。这是Task&lt;Location[]&gt;。所以你在异步调用完成之前处理代理(通过Close)。

    解决方法是在调用Close 之前先调用await Task,就像您的原始代码所做的那样。这应该可以解决问题:

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

    【讨论】:

    • 这正是我的想法。谢谢!
    猜你喜欢
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    相关资源
    最近更新 更多