In diesem speziellen Fall, das Problem ist, dass Sie brauchen, um einige bedeutet, den Zugriff auf die List<Character> Characters
zu synchronisieren.
Beachten Sie die Signatur der Methode LoadCharacterData
:
public static async Task LoadCharacterData(Client player)
{
// ...
}
Es ist ein async Methode. Es wird nicht synchron laufen. Das heißt, wenn Sie CharacterController.LoadCharacterData(player);
anrufen, müssen Sie warten, bis es fertig ist.
Sie können dies erreichen, indem Sie den Anrufer async
anrufen und await
verwenden. Obwohl, ich vermute, dass Sie die Signatur von OnPlayerDownloaded
nicht ändern können. In diesem Fall würde nehme ich die retunred Task
und warten auf sie:
public void OnPlayerDownloaded(Client player)
{
var task = CharacterController.LoadCharacterData(player);
task.Wait(); // <---
Console.WriteLine("TEST: " + CharacterController.Characters[0].Name + CharacterController.Characters[0].Surname);
}
Hinweis: auf Ihrem Code, müssen Sie eine Warnung auf der folgenden Zeile bekommen:
List<Character> Characters = new List<Character>();
Hier , Sie verwenden nicht die Eigenschaft. Sie erstellen eine lokale Variable mit demselben Namen.
Jetzt gibt es eine weitere versteckte Problem ... List<Character>
ist nicht Thread-sicher. Betrachten Sie das Problem, das es verursachen würde, wenn Sie zwei Aufrufe an LoadCharacterData
zur gleichen Zeit ausgeführt hätten! - List<Character>
ist nicht dafür ausgelegt.
Ich schlage vor, LoadCharacterData
neu zu schreiben Task<List<Characater>>
zurückzukehren und haben es die List<Character>
zurückkehren, anstatt sie an die Öffentlichkeit Eigenschaft schreiben:
public static async Task<List<Character>> LoadCharacterData(Client player)
{
var filter = new BsonDocument("NameOfTable", player.Name);
var characters = await DatabaseManager.Characters.Find(filter).ToListAsync();
List<Character> result = new List<Character>();
foreach (var character in characters)
{
result.Add(new Character
{
Name = character.Name,
Surname = character.Surname
}
);
}
return result;
}
Alternativ könnte man bedenkt, Zugriff auf das Eigentum zu synchronisieren oder faul Initialisierung verwenden ... aber beachte, dass List<Character>
nichts über die Client
sagt. Ich weiß nicht, ob es mehrere Anrufe zu LoadCharacterData
mit verschiedenen Client
geben kann, die sich gegenseitig überarbeiten können.
Könnten Sie genauer auf was "Es funktioniert nicht" bedeutet? - Ich vermute, dass Sie eine NULL-Referenzausnahme erhalten, weil 'LoadCharacterData' nicht' Characters' initialisiert hat (beachten Sie, dass es sich um eine asynchrone Methode handelt). In diesem Fall haben Sie dann Zugriff auf ein in einer anderen Datei definiertes Feld. Übrigens ist 'List' nicht Thread-sicher. –
Theraot
Ja, Entschuldigung. Ich hatte einen Fehler: System.NullReferenceException: Die Objektreferenz zeigt nicht auf eine Instanz des Objekts. Sie haben Recht. Vielleicht beraten Sie, wie man am besten remake? – Joseph