2016-10-03 4 views
3

Ich programmiere ein Spiel der Unity Engine und ich bin derzeit in das folgende Problem:Vergleichen Parameter mehrerer Rückrufe

ich eine Methode, die sein Ergebnis asynchron die Parameter einer Callback-Funktion zurückgibt. Ziemlich einfach, sieht es so aus:

public void CalculateSomething(- PARAMETERS - , Action<float> callback) 

Ich muss diese Methode in einer Schleife für verschiedene Parameter aufrufen.

foreach(float f in manyFloats){ 
    CalculateSomething(f, myCallback); 
} 
void myCallback(float f){ 
    ...compare this result value to the other values?... 
} 

Nun möchte Ich mag den resultierenden Schwimmer vergleichen, die mit den verschiedenen Rückrufen kommen. Sagen wir einfach, ich möchte den höchsten Wert unter diesen Floats finden. Wie mache ich das?

Ich hatte die Idee, die Ergebnisse in einem Array-Feld zu speichern und nur zu vergleichen, nachdem es voll ist, aber ich weiß nicht, wie man überprüft, ob alle Rückrufe bereits erledigt sind.

Idealerweise möchte ich es vermeiden, meine Klasse mit einem Feld wie diesem zu verschmutzen, aber es wäre in Ordnung, wenn es keinen anderen Weg gäbe. Die CalculateSomething Funktion ist Teil einer Bibliothek, also kann ich sie nicht ändern. Alles andere ist variabel.

+1

benötigen Sie die Rückrufkonfiguration, die Sie jetzt haben? Mit diesem Beispielcode scheint es am einfachsten zu sein, einen Wert von 'CalculateSomething' zurückzugeben, um ihn einer Liste hinzuzufügen, und Sie können Werte nach der Schleife vergleichen. – Jonesopolis

+1

Das 'CalculateSomething' stammt aus einer anderen Bibliothek, das muss also bleiben. Alles andere könnte geändert werden. Über Ihren Vorschlag: Woher weiß ich, wenn die Liste gefüllt ist? Wie überprüfe ich, ob jeder Rückruf bereits beendet ist? Könnte ich das tun, ohne meine Klasse zu verschmutzen? Edit: Whoops, das sollte nicht schon gesendet werden ... – MaXL130

Antwort

1

Hier ist der Deal. Sie haben es richtig gemacht, das Array zu erstellen und die Werte zu speichern und sie zu vergleichen, wenn alle Rückrufe durchgeführt wurden. Daher ist das Problem, dass Sie nicht wissen, wann alle Rückrufe zurückgegeben werden. Aber Sie wissen, wie viele Rückrufe gibt es basierend auf der Anzahl Ihrer Herkunft manyFloats Variable. Alles, was Sie tun müssen, ist, einen Zähler zu behalten und ihn jedes Mal hinzuzufügen, wenn ein Rückruf zurückgegeben wird. Und überprüfen Sie, ob es gleich der Anzahl von vielen Flotten ist, dann können Sie den Vergleich durchführen:

int count = 0; 
void myCallback(float f) 
{ 
    ... usual stuff 
    ... then 
    if(count == manyFloats.Count) 
    { 
     // do the comparison 
    } 
    else 
    { 
     count ++; 
    } 
} 
+0

Das wird funktionieren, danke! – MaXL130

1

Anstatt ein Callback-basiertes Modell zu verwenden, sollten Sie ein Task basiertes Modell verwenden. Lassen Sie CalculateSomething einen Task<float> zurückgeben, anstatt einen Rückruf zu haben. Dadurch können Sie die TPL verwenden, um diese Task Objekte zu komponieren durch das Schreiben von Code wie:

var highestResult = (await Task.WhenAll(manyFloats.Select(CalculateSomething))).Max(); 

Wenn Sie die Methode nicht bearbeiten können selbst dann Ihre eigenen Wrapper erstellen, die das Verfahren in einer Task-basierte Version transformiert.

+0

Danke für Ihre Antwort. Kann ich das tun, ohne 'CalculateSomething' zu ändern? Die Sache ist, dass es Teil einer Bibliothek ist. – MaXL130

+0

@ MaXL130 Ich habe das in meinem letzten Satz angesprochen. – Servy

+0

Ja hast du ... sry für das Vermissen. Also werde ich anfangen, mehr über Aufgaben und deren Verwendung zu lernen. – MaXL130

0

Also, wenn wir keine Kontrolle über CalculateSomething Funktion haben, können wir noch Max-Wert speichern und Vergleich in unserem Callback machen. So etwas wie das:

void callbackFunction(float numb){ 
    if (numb > maxNumb) //maxNumb is global 
     maxNumb = numb; 
} 

dann können Sie Ihre foreach-Schleife verwenden, um durch Ihr Array zu gehen. Denken Sie daran, dass Sie Ihre globale Variable maxValue deklarieren und sie zunächst als Mindestwert festlegen müssen.

Auch wenn Sie nicht Min/Max-Vergleich machen, und es ist etwas komplizierter, können Sie es immer noch in Callback-Funktion tun. Keine Notwendigkeit für Arrays, weil auch mit Arrays, wenn Sie es mit Single-Pass-Through-Array tun können - Sie können es in einer Callback-Funktion tun.

+0

Ich kann die Funktion 'CalculateSomething' nicht ändern, da sie Teil einer Bibliothek ist. Also ich denke, das würde nicht funktionieren? – MaXL130

+0

Dies leidet unter all diesen Problemen (http://stackoverflow.com/questions/39836595/compare-parameters-of-multiple-callbacks-in-c-sharp#comment66963122_39836595), die das OP an anderer Stelle erwähnt hat. – Servy

+0

Ich habe meine Antwort unter Berücksichtigung aller oben genannten Dinge aktualisiert. Ich glaube immer noch, dass es ein besserer Weg ist, als alles in Array zu speichern und dann buchstäblich dasselbe zu tun. – GSazheniuk