C# - 如何多次使用API​​调用的结果

时间:2017-08-02 11:13:39

标签: c#

我陷入了这样的境地。 我有2种方法

public class Test
{
   public void Test()
   {
        A();
        B();
   }

    Method A    
    private async Task(returntype) A()   
    {   
       var items = await C();
       var myItems = activityItems.Where(x => x.name="my");  
       return myItems;  
    }

    Method B
    private async Task(returntype) A()      
    {      
       var items = await C();
       var myItems = activityItems.Where(x => x.name="all");  
       return myItems;
    }     

    Method C is await method
    private async Task(ResultList) C()    //appserver call
    {   
       var itemsList= await Ioc.Resolve<IServiceCall>().InvokeAsync<IManager, ResultList>(this.MakeWeakFunc<IManager, ResultList>((service) =>
                                       service.GetCounts()));
       return activityItemsCount; 
    }
}

现在我需要只调用一次'C'而不是两次(一次来自A,一次来自B),如上所述。

这非常重要,因为api调用成本很高,而且我无法为执行相同的工作两次调用api

我该怎么办?
例如:
Api电话返回10个项目
A使用前10个中的5个 B使用接下来的5个项目中的5个

2 个答案:

答案 0 :(得分:0)

根据您编辑的问题,您使用的是哪种类型仍然不明显,但希望以下代码足以让您前进。我个人更喜欢在C()方法中维护缓存,因为它封装在一个地方并且更容易维护。

public class ApiCall
{
    private IEnumerable<Item> _result = null;
    private async Task<IEnumerable<Item>> A()
    {            
        if (_result == null)
        {
            _result = await C();
        }

        var items = _result;
        var myItems = items.Where(x => x.name == "my");
        return myItems;
    }

    //Method B
    private async Task<IEnumerable<Item>> B()
    {
        if (_result == null)
        {
            _result = await C();
        }

        var items = _result;
        var myItems = items.Where(x => x.name == "all");
        return myItems;
    }

    //Method C is await method
    private async Task<IEnumerable<Item>> C()    //appserver call
    {
        var itemsList = await Ioc.Resolve<IServiceCall>().InvokeAsync<IManager, ResultList>(this.MakeWeakFunc<IManager, ResultList>((service) => service.GetCounts()));
        return itemsList;
    }
}

原帖

在不知道api是如何工作的情况下这可能有点困难,但我会假设你通过api调用一个数字然后你回来了一个字符串。

private Dictionary<int, string> localCache = new Dictionary<int, string>();
public string C(int id)
{
    if (localCache.ContainsKey(id))
    {
        return localCache[id];
    }
    else
    {
        string returnedFromApi = SomeApiCall(id);
        localCache.Add(id, returnedFromApi);
        return returnedFromApi;
    }
}

这是非常基本的,但可以完成工作。您可能需要考虑根据需要缓存到磁盘或数据库。

答案 1 :(得分:0)

  

现在我需要只调用一次'C'而不是两次(一次来自A,一次来自B),如上所述。

然后调用一次,并将结果传递给每个方法。如果你的旧代码看起来像这样:

var a = await A();
var b = await B();

然后您的新代码可能如下所示:

private async Task<List<TResult>> C();
private async Task<TA> A(List<TResult> items);
private async Task<TB> B(List<TResult> items);

var items = await C();
var a = await A(items);
var b = await B(items);