2017-08-02 94 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