Ich habe eine schwierige Zeit zu verstehen, die TPL und ich kann nicht viele klare Artikel darüber finden. Die meisten scheinen vereinfachte Beispiele mit Lambda-Ausdrücken zu verwenden..NET TPL Deklaration Probleme
Ich habe eine C# Funktion
int[] PlayGames(int[][] boardToSearch, int numGamesToPlay) {…}
ich dieses schraubbaren mit .NET 4.6 TPL in C# machen wollen. Ich möchte bis zu 8 dieser Funktionen gleichzeitig starten, warten bis alle fertig sind, die Ergebnisse erfassen und weitermachen.
Ich kann nicht scheinen, die Typen richtig zu machen und es funktioniert nicht wie erwartet.
Hier ist, was ich bisher habe:
Task<int[]> PlayGames(int[][] boardToSearch, int numGamesToPlay) {…code that takes a long time…}
private int FindBestMove(int[][] boardToSearch, int numGamesToPlay)
{
…
var taskList = new List<Task>();
taskList.Add(Task.Factory.StartNew(() => { return PlayGames(boardToSearch, numGamesToPlay); }));
taskList.Add(Task.Factory.StartNew(() => { return PlayGames(boardToSearch, numGamesToPlay); }));
// Tests
Task a = taskList.First();
var a1 = a.Result; // NOT ALLOWED!? Viewable in debugger, cannot access it.
var b = Task.FromResult(a);
var b1 = b.Result; // Works but cannot access child member Result. Debugger sees it, I can’t!?
Task.WaitAll(taskList.ToArray());
…
}
Hier sind meine Fragen
Wie kann ich den Lambda-Ausdruck
() => { return PlayGames(boardToSearch, numGamesToPlay); }
entfernen? Ich möchteFunc()
irgendwie verwenden, aber ich kann nicht für das Leben von mir herausfinden, wie man "Task.Factory.StartNew<int[]>(Func(PlayGames(boardToSearch, numGamesToPlay)))
" sagt.Warum muss ich
StartNew()
verwenden? Wenn ichtaskList.Add(PlayGames(int[][] boardToSearch, int numGamesToPlay))
mache, macht es das synchron !? Wie lautet die korrekte Syntax zum Hinzufügen einer Aufgabe zu einer Liste auf diese Weise? Muss ich einen Func von einigen Arten erklären, die ich zu etwas wienew Task(Func(PlayGames))
übergebe?Wenn Sie die Variable a nach dem Ausführen der Zeile Task a = taskList.First() betrachten, wird im Debug-Fenster eindeutig ein Member namens Result angezeigt. Und wenn ich dieses Ergebnis erweitere, enthält es die richtigen Daten! Aber wenn ich auf "Add watch" klicken, bekomme ich einen Fehler! Und wenn ich a.Result mache, gibt mir der Compiler denselben Fehler! ?? Der Debugger sagt also, dass er da ist, aber ich kann ihn nicht selbst sehen! Ich kann es von einem Objekt aus durchsuchen, aber nicht direkt. Ich fügte einen Screenshot von diesem ein, damit andere sehen konnten.
Was ist der sauberste Weg, dies mit .NET 4.6 zu tun, während Sie sich von Lambda-Ausdrücken fernhalten. Ich möchte alle Arten und die Erklärungen sehen.
Beigefügt ist ein Screenshot von meinem Debugger, so können Sie sehen, was ich mit .Result
Ich habe meinen Code so gemacht, aber wie kann ich auf das Ergebnis zugreifen? Das lässt mich das nicht machen 'foreach (var taskGameResults in taskList) für (int i = 0; i <4; i ++) moveAverageScores [i] + = taskGameResults.Result;' Ich bekomme 'Fehler CS1061 \t' Task 'enthält keine Definition für' Ergebnis 'und keine Erweiterungsmethode' Ergebnis 'ein erstes Argument vom Typ' Task 'konnte gefunden werden (fehlt eine Using-Direktive oder eine Assembly-Referenz ?) ' Dies ist der gleiche Fehler, den ich oben beschrieben habe. Es macht mich verrückt, da dies einfach erscheint! Vielen Dank für Ihre Hilfe. – ejkitchen
Um Zugriff auf das Ergebnis zu erhalten, müssen Sie den Task 'anstelle von' Task' verwenden. Ich habe die Antwort bearbeitet, um das zu zeigen. –
MaKCbIMKo
Danke! Das hat funktioniert. Wenn du Zeit hast, kannst du mir einfach zeigen, wie ich alles deklariere, damit ich keinen Lambda-Ausdruck an Task.Run weitergeben muss? Es ist in Ordnung, wenn es einen anderen Typ hinzufügt. Ich möchte nur sehen, wie es gemacht wird. Außerdem habe ich vergessen, die zu Task.Run hinzufügen und es funktionierte immer noch !? Sollte ich nicht einen Fehler bekommen? Es funktioniert in beide Richtungen. Für mich scheinen sie zwei verschiedene Arten zu sein, nein? –
ejkitchen