2017-08-02 24 views
-2

我陷入了这种情况。 我有2种方法C# - 如何多次使用API​​调用的结果

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

现在我需要(从乙一旦从A和一次)调用“C”只是一次而不是两次,如上所述。

这是非常重要的,因为API调用是昂贵的,我买不起调用API两次做同样的工作

我怎么能这样做?
例如:
API调用返回10项
A使用前5出10
B的基于你编辑的问题,采用未来5出的10个项目

+5

请提供真实的代码,而不是伪代码。请编辑您的文章,并在文字和代码之间进行区分。你的问题似乎没有与异步/等待相关。取而代之的是,您正在询问如何多次使用API​​调用的结果。问题在哪里? – gdir

+0

所以基本上你希望方法C缓存结果,如果A或B制作相同的API,它们会从缓存中返回结果,而不是再次调用API? –

+0

@JonClarke有什么办法可以不使用本地缓存。就像有一个私人变量说“结果”。将api调用的结果存储在此变量中,并在方法'A'和方法'B'中使用它。 – ZigZig

回答

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

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

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

如果我在构造函数中调用A()和B()会怎么样。在API调用返回到项目(上面提到的变量)之前,控制可以进入A()和B()。 – ZigZig

+0

在构造函数中调用异步方法存在问题。我建议你使用[这些解决方案之一](http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html)。 –

+0

谢谢你的帮助 – ZigZig