2017-08-02 2 views
-2

Ich bin in einer Situation wie dieser stecken. Ich habe 2 MethodenC# -wie das Ergebnis eines API-Aufrufs mehrmals verwenden

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

Jetzt brauche ich statt zweimal nur einmal ‚C‘ zu nennen (einmal aus von A und einmal von B), wie oben erläutert.

Dies ist sehr wichtig, weil api Anruf teuer ist und ich kann nicht leisten, api zu nennen zweimal zu tun gleiche Arbeit

Wie kann ich das tun?
Beispiel:
Api Aufruf liefert 10 Stück
Ein erstes 5 von 10
B verwendet nächsten 5 von 10 Artikel

+5

Bitte echten Code zur Verfügung stellt, nicht Pseudo-Code. Bitte bearbeiten Sie Ihren Beitrag und unterscheiden Sie zwischen Text und Code. Ihr Problem scheint nicht mit async/await verwandt zu sein. Stattdessen fragen Sie, wie Sie das Ergebnis eines API-Aufrufs mehrmals verwenden können. Wo ist das Problem? – gdir

+0

Also im Grunde wollen Sie die Methode C die Ergebnisse zwischenzuspeichern und wenn A oder B die gleiche API machen, geben sie die Ergebnisse aus dem Cache zurück, anstatt die API erneut aufzurufen? –

+0

@ JonClarke Gibt es einen Weg, ohne lokalen Cache zu verwenden. Etwas wie eine private Variable sagen "Ergebnis". Speichern Ergebnis des API-Aufrufs in dieser Variable und verwenden Sie es in der Methode 'A' und Methode 'B' – ZigZig

Antwort

0

Basierend auf Ihrer editierten Frage verwendet es immer noch nicht klar ist, welche Arten Sie verwenden , aber hoffentlich sollte der folgende Code genug sein, um dich in Gang zu bringen. Persönlich bevorzuge ich es, den Cache in der C() -Methode zu halten, da er an einer Stelle gekapselt ist und leichter zu warten ist.

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

Original-Beitrag

Ohne zu wissen, wie die api funktioniert dies ein wenig schwierig sein könnte, aber ich werde Ihnen die api rufen Sie eine Nummer übergeben zu übernehmen und Sie erhalten wieder einen String.

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

Dies ist sehr einfach, aber würde die Arbeit erledigen. Je nach Ihren Anforderungen sollten Sie die Zwischenspeicherung auf Festplatte oder Datenbank in Betracht ziehen.

0

Jetzt muss ich 'C' nur einmal anstatt zweimal aufrufen (Einmal von A und einmal von B) wie oben erklärt.

Dann rufen Sie es einmal, und übergeben Sie die Ergebnisse an jede Methode. Wenn Ihr alter Code sah wie folgt aus:

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

dann der neue Code könnte wie folgt aussehen:

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

Was ist, wenn ich A() und B() im Konstruktor aufrufen. Die Steuerung kann in A() und B() gelangen, bevor ein api-Aufruf an Elemente zurückgegeben wird (oben erwähnte Variable). – ZigZig

+0

Der Aufruf von asynchronen Methoden in einem Konstruktor ist problematisch. Ich empfehle Ihnen, [eine dieser Lösungen] (http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html) zu verwenden. –

+0

Vielen Dank für Ihre Hilfe – ZigZig

Verwandte Themen